Troubleshooting

The symptoms operators actually hit — a market that reads ACTIVE and prints nothing, a start that is refused, a pool that will not fund or withdraw, disagreeing volume figures and a price being driven twice — with the cause and the fix for each.

10 min readUpdated 3 August 2026troubleshooting, diagnostics, gates, engine

Work down this page in order. Most reports resolve at the first two checks.

Quick diagnostics

    • Admin → System → Extensionsai_market_maker enabled, and ecosystem enabled
    • Admin → System → Cron — seven jobs under ai_market_maker, none failed
    • Dashboard masthead — an engine process is named, and leadership is arbitrated by Redis or the database
    • Dashboard quoting meter — the market says Quoting, not Not quoting with a gate named
    • Market detail → Overview — the last known price is changing
    • Server log, filtered to AI_MM — the engine states its own refusals there

The market says ACTIVE and nothing is happening

This is the single most common report, and the status column is not the answer. The engine applies four hard gates and a market failing one keeps its ACTIVE badge.

A print needs two sides. Open the market's Bots tab and count the ACTIVE ones. The dashboard names this as "needs active bots" and links to the market.

Log line: Need at least 2 active bots for SYMBOL, have: 1

Note that a bot can only be activated while its market maker is ACTIVE — if you stopped the market and paused bots individually, activate the market first.

With realLiquidityPercent above 0 and a total value locked of zero, there is nothing to back an order. Either fund the pool or set real liquidity to 0.

Log line: Real liquidity enabled but no pool for SYMBOL

currentDailyVolume has reached maxDailyVolume. The market stops quoting until the UTC daily reset. Raise the budget, or use Reset daily counters on the Configuration tab to hand out a fresh allowance now — understanding that the budget existed for a reason.

Log line: Daily volume limit reached for SYMBOL: x/y

This gate is not visible on any screen. It is evaluated from price history held in the engine's memory, which no query can reach, so the dashboard will still report the market as quoting.

Log line, throttled to once a minute: High volatility (x.xx%), skipping SYMBOL

Either raise volatilityThreshold on the market, lower baseVolatility, or turn pauseOnHighVolatility off.

Global Pause or Maintenance Mode on the settings screen suppress trading across every market. Prices and charts keep advancing, which is exactly what makes this one hard to spot: the chart looks alive and the tape is empty.

A market will not start

totalValueLocked is zero. Deposit to the pool first — see Funding the pool.

aiMarketMakerMinLiquidity is checked against the pool's quote balance, not its TVL. A pool holding plenty of base and nothing in quote fails this. Deposit quote, or lower the setting.

The engine may not be running in the process that answered. The response says so: "recorded as ACTIVE, but the market-making engine is not running in this process yet." Wait one engine cycle. If it never starts, check the cron registry and the leadership block on the dashboard.

The setting labelled Max Concurrent Bots actually caps the number of markets the engine will drive. Raise it on the settings screen. The dashboard also raises an alert when the engine holds fewer markets than the database says are ACTIVE, which is the same fault seen from the other side.

The market maker has no bot rows at all. This should not happen — six are created in the same transaction as the market — but a partially rolled-back creation on an old build could produce it. Delete and recreate the market maker.

No ecosystem markets to select

The create wizard offers only ecosystem markets that do not already have a market maker. A pair that already has one will not appear — the marketId column is unique and the API refuses the duplicate with "AI Market Maker already exists for this market".

If the list is empty entirely, you have no ecosystem markets. Create one under the Ecosystem addon first.

The pool will not fund or will not release

Pause or stop the market first. The same guard applies to the rebalance calculation, in both REPORT and EXECUTE modes.

An older build could leave a market the engine had lost in a state where stop reported success without changing anything and pause returned a server error — which locked the pool, because withdrawals refuse an ACTIVE market. Update. Both actions record the change properly now, and stopping also clears any synthetic depth left on the order book.

A build before v6.1.5. The wallet ledger key was derived from (pool, currency) alone, so a pool could be funded exactly once per currency, ever — and whatever was left after a first withdrawal could never be taken out. Update; no data is lost.

Funding is an internal transfer between two balances the platform already holds. An older build routed it through the deposit-address machinery, so an admin holding a good balance in a token whose chain was not configured on that server could never fund the market. Update.

The price is wrong or is moving twice as far

Symptoms that all have this one cause: the price moves roughly twice as far as configured; stopping a market from the admin panel leaves it publishing; synthetic order book levels reappear after being cleared; the 1-minute candle disagrees with itself.

The engine must tick exactly once per deployment. Check the dashboard's engine block: if leadership is arbitrated by "none", neither Redis nor the database lease row could be reached and every process that starts the engine believes it leads. Restore Redis, or the ai_market_maker_engine_lease table, and restart.

Cluster mode, a rolling restart whose old worker has not exited, and two development shells all produce this.

Other price symptoms:

  • A step change on every chart after a restart — a build before v6.1.5, which kept no price state and began each start on a fresh path, seeded around the configured target rather than the live price. The engine now checkpoints every two minutes and resumes.
  • "No price yet" on a market you just started — expected. The first checkpoint is a couple of minutes out.
  • The price leaves its band — the containment force engages only in the outer 20% of the range. If the market sits at the edge, widen the range; the dashboard reports at range edge as its own state so you can act before it leaves.

Figures that disagree

currentDailyVolume is zeroed at the UTC daily reset. It is volume today, not a rolling day. This is normal and the dashboard labels it accordingly.

By design. The dashboard sums every market whatever its status; the analytics screen still sums ACTIVE markets only. Pausing a market part-way through a day removes it from the analytics figure along with the volume it had already traded.

A trade between two of the platform's own bots has no profit or loss — both sides are the house. On a market at 0% real liquidity, realised P&L is legitimately zero however busy the tape looks.

Different ledgers. All-time comes from each bot's lifetime accumulator; the period figures come from a per-fill ledger that had no writer until v6.1.0, and the individual fills before that were never captured. The screen states when the ledger begins.

Every summary written before v6.1.5 recorded zero volume, zero buys and zero sells, for the server's local day rather than the UTC day. Summary history cannot be deleted, so those rows remain. Everything written since is correct.

A build before v6.1.5, which reported 50% on the list and 65% on the detail screen with the counts derived from the rate. None of it was measured. Update; those screens now show blanks where there is nothing to measure.

Orders pile up in the Ecosystem book

The backend loads open orders at startup. A build before v6.1.5 never cancelled its own quotes — one live market reached 704,353 open orders, which was enough to make the site serve connection refused while the log filled with successful startup messages.

Update, then clean up. Orders already resting do not disappear on update:

pnpm eco:mm:orders          # report what is there
pnpm eco:mm:orders:clean    # cancel them

The cleanup reads each order's true owner from the ecosystem row itself, which is why it can cancel rows the engine cannot.

If a current build warns that a market is at its resting-order ceiling:

N real liquidity orders are already resting, at the ceiling of 500.

That is the ceiling working. It means quotes are not being cancelled — check the expiry sweep in the log before raising maxRestingRealOrders or AI_MM_MAX_RESTING_REAL_ORDERS.

Real users' orders vanish from the book

Fixed in v6.1.5. Every AI trade used to rebuild the market's aggregated order book by deleting every level for that symbol and writing its own back — taking real users' resting limit orders, and copy-trading followers', with them. They reappeared minutes later when a repair pass ran. While a level was missing it could not be matched against, and anything pricing off that book read the same gap.

The menu entry is missing

Admin → System → Extensions. With the row off, no menu entry renders and no cron registers.

The addon's keys were renamed from a dotted spelling (ai.market.maker) to an underscored one (ai.market_maker), and the migration deletes the old rows. Grants carry over for most of the family, but access.ai.market_maker.market — the Markets list screen — receives grants from a retired ai.trading.market family rather than from the addon root. Re-grant the underscored key.

Super Admin bypasses the gate outright, so an owner testing their own admin account sees nothing wrong.

Cron jobs are missing or doing nothing

The extension row is off. The scheduler reads the enabled-extension set from the database and registers addon jobs from it.

The ecosystem extension is disabled, so no process in the deployment boots an ecosystem matcher. The market maker trades ecosystem markets, so there is nothing to quote — this is not about which process cron runs on. The other six jobs still run and are unaffected.

Correct behaviour under CRON_MODE=only. The engine's bots enqueue into the ecosystem matcher, so the job runs where the matcher does — the web process drives the same handler from its own supervisor tick.

A build before v6.1.5. The pool rebalancer and the external price sync both required the global trading switch to have been explicitly saved once, and it is not set on a fresh install. Every other job already treated an unset switch as on. Both now do the same.

Configuration changes have no effect

Before v6.1.5, changing a market's volatility, bias, price mode, target price, price range or forced phase — or any of a bot's settings, or its status — showed a success message, updated the database and left the running market behaving exactly as before until the next full reload, which in practice meant up to 24 hours.

A second defect sat behind it: the engine replaced its configuration wholesale on refresh while the parts that place orders and execute trades still read the copy handed to them at startup. That is why Max Daily Volume and the per-bot trade limits stopped being enforced once a market's configuration had been touched at all.

If bot edits in particular are not sticking, see the warning on Bots — the old form posted field names the server does not read, and nine of the ten risk-tolerance slider positions were refused outright, taking the rest of the request with them.

Every emergency stop in history says the same thing

The dashboard's button posted an empty request to an endpoint that has always accepted a reason and has always written it onto each market's history entry. So every such entry already recorded reads "Emergency stop triggered by admin". Those rows cannot be reconstructed. From v6.1.6 the dashboard requires a written reason; the panel on the settings screen still does not.

Collecting information for support

Have these ready:

  1. The addon version, from Admin → System → Extensions.
  2. Whether ecosystem is enabled, and whether Scylla is reachable.
  3. The dashboard's engine block — process, leadership and what arbitrated it.
  4. The affected market's quoting state and, if it is not quoting, the named gate.
  5. Server log lines tagged AI_MM, AI_MM_WS or AI_RISK_MONITOR around the time of the problem.
  6. The market's recent history entries, which name every configuration change and who made it.