Troubleshooting
Known issues and fixes, grown from real setup experience.
Boot fails: "Invalid environment configuration"
The app validates env at boot. The message lists exactly which vars are missing or invalid. Common cases:
JWT_ACCESS_SECRET must be at least 32 characters— generate a strong secret (node -e "console.log(require('crypto').randomBytes(48).toString('base64url'))").CORS_ORIGINS must be set in production— set your real front-end origins; the app won't reflect-any-origin with credentials in prod.
Boot fails: placeholder JWT secret in production
In NODE_ENV=production the app rejects secrets containing change,
dev-only, etc. Use real, unique secrets per installation.
psql: FATAL: role "postgres" does not exist
Homebrew Postgres creates a role named after your OS user, not postgres.
Set DB_USERNAME in .env to your username (e.g. whoami).
Health endpoint returns 503
One dependency is down. The error object names it:
database: down→ Postgres unreachable / wrong creds.redis: down→ Redis unreachable (the check times out after 2s rather than hanging).
npm ci fails in Docker/CI: lock file out of sync
Regenerate the lock file so it's platform-consistent:
docker run --rm -v "$PWD:/app" -w /app node:20-alpine \
sh -c "rm -f package-lock.json && npm install --package-lock-only"
Ledger write rejected
The ledger enforces invariants at the DB level. Expected rejections:
- "Unbalanced ledger entry … for currency" — debits ≠ credits within a currency.
- "must have at least two postings" — an entry needs ≥2 legs.
- "Ledger rows are immutable" — never UPDATE/DELETE; post a reversing entry instead.
source: docs/troubleshooting/README.md (ships identically in the product zip)