Troubleshooting
AI Investments failures that look like nothing is wrong — investments that never settle, the tab that will not appear, payouts nobody can explain, and the queries that tell you which is which.
Most problems in this addon are quiet. Settlement swallows its own errors on the
user-facing path, the affiliate and email legs are best-effort by design, and an
investment that cannot be settled is deliberately left ACTIVE rather than
marked failed. That is the right behaviour — none of it should block a page or
strand money — but it means the symptom you get is usually "nothing happened".
Start with the database. These queries answer most tickets faster than any screen.
Diagnostic queries
SELECT i.id, i.userId, i.amount, i.symbol, i.status, i.createdAt,
d.duration, d.timeframe
FROM ai_investment i
LEFT JOIN ai_investment_duration d ON d.id = i.durationId
WHERE i.status = 'ACTIVE' AND i.deletedAt IS NULL
ORDER BY i.createdAt ASC;Work out the end date by hand from createdAt and the term — hours, days,
weeks × 7, months × 30. Anything already past its end date is a settlement that
has not run.
SELECT i.id, i.userId, i.amount, i.symbol, i.createdAt
FROM ai_investment i
LEFT JOIN ai_investment_plan p ON p.id = i.planId AND p.deletedAt IS NULL
WHERE i.status = 'ACTIVE' AND i.deletedAt IS NULL AND p.id IS NULL;SELECT t.userId, t.amount, t.currency, t.createdAt, t.referenceId
FROM transaction t
LEFT JOIN ai_investment i ON i.id = t.referenceId
WHERE t.type = 'AI_INVESTMENT' AND i.id IS NULL;SELECT i.id, i.userId, i.amount, i.symbol, i.status, i.createdAt
FROM ai_investment i
LEFT JOIN transaction t
ON t.referenceId = i.id AND t.type = 'AI_INVESTMENT'
WHERE t.id IS NULL AND i.deletedAt IS NULL;That last one is the dangerous list. Every row on it will be paid out at maturity without ever having taken money from the user.
Symptoms
Check /admin/system/cron for Process AI Investments. If it is not listed at
all, the ai_investment extension row is not enabled — the cron registry is
gated on it and the job is only registered while the extension is on.
If it is listed but has never run, the cron process itself is down. Settlement is its only automatic path.
The confusing case is a cron that is down while some users are being paid anyway: the user's own investment list settles their matured investments in-line when they open it. Two people who bought the same plan on the same day can be settled days apart, purely by who logged in. That is the fingerprint of a stopped cron.
Search the backend log for AI_INVESTMENT_UPDATE and the investment id.
The most likely cause is a payout wallet that cannot be resolved. Settlement
tries the wallet on the original funding transaction first, then a wallet
matching the user, the investment's type, and the quote half of its symbol.
If neither resolves it rolls back, writes an ALERT naming the investment, the
user, the symbol, the type and whether the funding transaction was found, and
leaves the row ACTIVE on purpose — writing a terminal status without a refund
would strand the principal silently.
Fix the wallet (usually: the user has no wallet of that type in that currency because it was archived) and the next run will clear it.
This resolves itself. A payout that already exists — because the admin
completion door ran, or because the row was moved back to ACTIVE — is detected
on the next run through the unique <id>_roi reference. Settlement treats the
collision as proof the money was paid, commits COMPLETED without re-crediting,
and suppresses the completion email so nobody is told twice.
If it is not clearing, the cron is not running. See the first entry.
Three things gate it, in this order:
- The
ai_investmentextension row must be enabled. The frontend reads the enabled-extension list from config; a hard reload after toggling is worth doing. - The panel only exists inside the trade workspace order form. There is no
standalone
/ai/investmentpage in this build, and/investmentis core's General Investment product, not this addon. - If the user is signed out or the
invest_aiKYC gate applies to them, the tab renders with an explanation in place of the form rather than disappearing.
They are on the standard trade page. The purchase form appears on both /trade
and /trade/pro, but the list of a user's own investments is in the Orders panel
of the Pro workspace only. Point them at /trade/pro.
This was fixed in 6.1.1 and will only appear on an install predating it. The
refund reused the funding debit's referenceId, which is unique platform-wide,
so the insert failed and the whole cancellation rolled back — for every
investment, on every install. Upgrade.
Check the transaction ledger for their investment id. You should see exactly one
AI_INVESTMENT debit with the bare id as its reference. A second debit is not
something this addon can produce — the purchase is a single transaction and the
idempotency key is derived from the newly-created investment id.
What you may be looking at instead is a refund with no matching charge, which means the funding transaction was destroyed by an old build's delete path. The funding row is preserved now.
If it is far too high, you are on a build predating 6.1.1: losses were added to
the profit total rather than subtracted. On one database that was checked, a
reported +1102 was really −48.
If it looks wrong on a current build, remember what the number is: wins add, losses subtract, draws contribute nothing, and rejected investments are excluded entirely. It is computed from the investments themselves and is a different figure from platform profit and loss, which only started recording AI investments from 6.1.1 and was never backfilled.
A failed load renders as an error card with a Try again button, not as zeros. If you are genuinely seeing a page of zeros with no error, either you have no investments, or you are on a build predating the fix — in which case a failed dashboard load was indistinguishable from a platform that had never sold anything.
That is the guard, and it is correct. Deletion is refused with a 409 while any investment references the row, live or historical, and the message says how many of each.
Deactivate the plan instead — its status toggle is right there in the table.
Durations have no status column, so remove the duration from every plan's
Duration options rather than deleting it. Existing investments keep working
either way.
Three possibilities, in order of likelihood:
- There is no Super Admin. The forfeited principal is credited to the oldest
user holding the Super Admin role. With none, the credit is dropped and the
log carries
[CRITICAL] Dropped platform fee — no Super Admin configured. - You are testing with the Super Admin account. Revenue collection is skipped entirely when the investor is the Super Admin, to avoid a circular credit that would inflate the reports.
- The settlements predate 6.1.1. The platform's own leg was not recorded before that release and is not backfilled.
Correct, if unhelpful. The AiInvestmentCanceled template is seeded and the
email helper accepts it, but nothing in the addon calls it. Neither the user
cancel, the admin status action nor the admin delete sends anything. Only
creation and maturity produce a message.
The in-app notifications created on purchase and on completion link to
/ai/investment/{id}, which is not a route in this build. The notification text
is still correct; only the link is dead.
That is what it does. There is no pro-rating anywhere in this product — the status action settles on the derived terms regardless of how much of the term has elapsed. Completing a one-day-old investment on a 12 MONTH plan pays the whole profit.
Use it to clear stuck rows, and check what it will pay before you press it.
Check the "no funding transaction" query above. The usual cause is
POST /api/admin/ai/investment/log being called directly — it writes a bare
record with no debit, and settlement will still pay it out by falling back to
resolving a wallet from the user, currency and type.
The admin table does not expose a create button. If rows are appearing this way,
something is calling the endpoint: check who holds create.ai.investment and
look for ADMIN_AI / Create AI investment entries in the audit trail.
Where the logs are
| Module | Written by |
|---|---|
AI_INVESTMENT_PROCESS |
The settlement scan — per-investment failures and the orphaned-plan rescue |
AI_INVESTMENT_UPDATE |
The settlement transaction — wallet resolution alerts and duplicate payouts |
AI_INVESTMENT_POST_PROCESS |
Completion email and notification failures |
AI_INVEST |
The user-facing create and cancel routes |
ADMIN_AI |
Every admin action, including the audit trail entries |
PLATFORM_FEE |
Dropped or skipped revenue on LOSS settlements |
The cron also broadcasts a live per-investment log to the cron screen while
processAiInvestments runs, which is the fastest way to watch a manual trigger.
If none of this matches what you are seeing, the lifecycle page has the exact order of operations for every path that moves money.