Troubleshooting
Known failure modes and how to fix them.
/health/ready returns 503
- DB unreachable —
docker ps | grep valura-ledger-dev-postgres; if not running, bring up the compose stack. - Migrations not at head —
docker exec valura-ledger-ind alembic current; if behind,docker compose ... up migrate-ind migrate-uae --no-deps.
Endpoint returns 404 after adding a new one
Uvicorn's --reload occasionally misses a change. Restart:
docker restart valura-ledger-ind
Wait 10 seconds, retry. If still 404, the endpoint isn't in the file that was
loaded — check grep for the route.
Endpoint returns 500 with sqlalchemy.exc.StatementError: A value is required for bind parameter
You have a :name fragment in a raw SQL string that SQLAlchemy is
interpreting as a bind param. Escape it — use a parameter binding:
# BAD
sql = text("... source_txn_id = r.order_id || ':fxsettle' ...")
# GOOD
sql = text("... source_txn_id = r.order_id || :fxsettle_suffix ...")
await session.execute(sql, {"fxsettle_suffix": ":fxsettle"})
/v1/india/* returns 200 but with zero data
Backend is up but hasn't ingested. Run the sync jobs.
/v1/india/treasury returns configured: false
GLOMOPAY_BASE_URL + GLOMOPAY_TOKEN aren't set. Set them, restart.
/v1/india/webhooks/glomopay returns 503
GLOMOPAY_WEBHOOK_SECRET unset. Refuses unsigned payloads.
/v1/india/webhooks/glomopay returns 401 "signature mismatch"
- Sender and receiver using the same secret?
- Sender signing the RAW body (not a re-serialized version)?
- Header format
X-Glomopay-Signature: sha256=<hex>?
Sync job succeeds but no rows land
dry_run: truein the request body (default is false, but check).- No customers matched — sync loops India customers only
(
viewtrade_account_refs IS NOT NULL); if provisioning hasn't run, there are no India customers. - Broker call failed and swallowed the error. Check backend logs:
docker logs valura-ledger-ind --tail 100
Reconciliation check says warn but nothing looks wrong
Check the variances:
curl -H "X-Ledger-Token: localdev" http://localhost:8078/v1/reconciliation/runs/<run_id>
The metadata.variances field lists the specific rows that failed.
Trial balance doesn't balance
The last posting rule is buggy. To diagnose:
SELECT t.txn_id, t.source, t.source_txn_id, t.txn_type,
SUM(j.debit_usd) AS dr, SUM(j.credit_usd) AS cr
FROM ledger.transactions t
JOIN ledger.journal_lines j ON j.txn_id = t.txn_id
GROUP BY t.txn_id, t.source, t.source_txn_id, t.txn_type
HAVING SUM(j.debit_usd) != SUM(j.credit_usd);
Reverse the offending transaction, fix the posting rule, re-ingest.
Frontend shows "error" badges for some customers on /nav
The live ViewTrade fetch failed for those customers. Common causes:
- The customer's ViewTrade account has an entitlement issue.
- The customer's
viewtrade_account_refs.b2c_user_idis stale.
Check the error message on the row.
pytest fails on Windows with asyncpg event-loop errors
Known issue. Use scripts/e2e_india.py for DB-backed cases; pure-logic pytest
works fine.