Skip to main content

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: true in 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_id is 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.