03 / Develop · Build · Common snags

Common snags ​

Failure modes across the whole build, most of which fail quietly — the app loads but something's off. Find your symptom in the left column.

SymptomCause & fix
veni: command not found after installing~/.local/bin isn't on your PATH. Add it, or re-run the installer from Set up with VENI_BIN_DIR pointing somewhere that is.
Not signed in — run 'veni login' first.Every command but login / update / uninstall / status and the diagnostics (whoami / doctor / version) needs a saved token. Run veni login, or set VENI_TOKEN for one run. The check is local, so a revoked token passes it and fails later at veni register instead. Why
App missing from the Shell launchpadIt must be running and registered — register it (UI or veni register) with "Allow local URL" for a localhost entry, then reload the Shell. See Register an app.
App loads but shows "Not signed in" on a cold load, fine after a refreshThe token-broadcast race — the Shell broadcasts its JWT once at login and a late-mounting remote misses it. The scaffold's UserProvider calls requestToken() on mount to fix this; a hand-written subscriber must too. The handshake
"Authentication Error — URL NOT FOUND" in the ShellVITE_API_URL is missing its /api suffix, so token exchange 404s. Fix ui/.env (reload in dev; rebuild if previewing). API + Auth
Exchange 401 / "Shell JWKS returned no usable signing keys"APP_ENV_SHELL_JWKS_URL points at the wrong Shell, or that Shell has no RSA key (APP_ENV_JWT_PRIVATE_KEY). The handshake
API calls blocked by CORSAPP_ENV_CORS_ORIGINS ships commented out, and unset it already allows your UI plus localhost:5173/4173 in dev. Uncommented, it replaces that list — so it must name both the Shell UI and your own UI. Restart the API after changing it. API + Auth
White screen / Cannot read properties of null (reading 'useState')Two Reacts. Keep shared: {} and don't set manualChunks in ui/vite.config.ts — the remote bundles its own React. Module Federation rules
created_by / updated_by land NULLThe handler didn't call a guard (requireAuth publishes the audit actor), or the repository doesn't extend AuditedRepository. The repository
A permission check 403s everyoneThe code never reached the permissions table, so the token's permissions is empty. Add it in a new migration (bun run db:generate --custom) and re-migrate — editing an already-applied 0001_seed.sql silently does nothing, because the migrator compares timestamps, not content. Then sign out and back in: codes are baked into the token at exchange. Authorization
Against Dev: the app never appears, or the console shows a mixed-content / blocked resourceThe UI must be a production build (bun run build && bun run preview), opened in Chrome. UI in the Shell · Cloud setup
ADD COLUMN … NOT NULL fails: contains null valuesYou added a required column to a table that already has rows. Split the migration: nullable column → backfill → SET NOT NULL. Multi-tenancy
Write dies with invalid input syntax for type uuid: ""The signed-in account has no organization — admin and system-admin are org-less, and the exchange falls back to an empty string, not null. Reject with a 403 before the query. Multi-tenancy
Consumer runs, but people who signed up earlier never appearA group created at '$' starts empty and no event will arrive for them. Backfill once from the Shell's GET /api/users. Integration
Cannot find module / no export RedisHelper from @venizia/ignisIt lives in @venizia/ignis-helpers, and takes { name, host, port, password } — not a URL. Integration
db:migrate left a half-applied schemaUse bun run db:migrate (the programmatic migrator), not db:migrate:kit — plain drizzle-kit can swallow a SQL error and still exit 0. Database

See also ​