Deployment issues
It refuses to start
Section titled “It refuses to start”Watcher fails fast rather than half-working. Each of these stops boot:
| Message mentions | Cause | Fix |
|---|---|---|
GOOGLE_GENERATIVE_AI_API_KEY … is required |
No Google key in the environment or the key store | Set it. It powers the evaluator, the embedder and the drafter, so it is required even for a run that ends up doing nothing |
MongoDB_URI is required |
The database URI is missing | Set it |
Failed to connect to MongoDB |
Wrong URI, cluster asleep, or your IP is not allow-listed | Use the full connection string; check the provider’s network access list |
AUTH_JWT_SECRET is required |
Running pnpm serve without it |
Generate a 32+ character secret |
AUTH_JWT_SECRET must be at least 32 characters |
Secret too short | Generate a longer one |
Invalid SCHEDULER_CRON |
Malformed cron expression | Fix the expression, or unset it for the default |
FIREBASE_SERVICE_ACCOUNT_JSON is not valid JSON |
The service account was pasted partially or re-escaped | Paste the file contents verbatim |
Generate a secret with:
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"It starts but nothing ever runs
Section titled “It starts but nothing ever runs”| Check | How |
|---|---|
| Are any watches enabled? | pnpm watches:list |
| Were the YAML files imported? | pnpm watches:import — the database is what runs |
| Is the scheduler on? | With SCHEDULER_ENABLED=false the service serves routes and never ticks (this is correct if a CI job owns the schedule) |
| Is the CI job running? | Check its run history; scheduled jobs are often disabled automatically on inactive repositories |
| Are the watches due? | Cron is UTC; a daily watch runs once per day |
Force one run to prove the pipeline end to end:
pnpm run-due:forceThe panel cannot reach the API
Section titled “The panel cannot reach the API”| Symptom | Cause | Fix |
|---|---|---|
| Browser console shows a CORS error | The panel’s origin is not in WEB_ORIGIN |
Add it (comma-separated for several) and restart the API |
| Requests 401 | No token, or an expired one | Sign in again; the default token lifetime is 7 days |
| Admin screens 403 | The account has the user role |
Only admin accounts may manage keys and models |
| Admin screens 503 | The key store is not configured | Set CONFIG_ENCRYPTION_KEY |
| First request after idle takes 30–60 seconds | The API host suspended the instance | Expected on free tiers; the app retries. Consider an always-warm host if it bothers you |
Two schedulers are running
Section titled “Two schedulers are running”Symptoms: duplicated work, faster-than-expected quota consumption, and watches running at times neither schedule explains.
Cause: a scheduled CI job and an always-on service pointed at the same database. The per-watch lock does not span processes.
Fix: SCHEDULER_ENABLED=false on the service, and let the CI job own the
schedule — or the reverse. Pick one clock.
Verifying an instance
Section titled “Verifying an instance”curl -s https://<your-api>/health # {"status":"ok"}curl -s https://<your-api>/config/status # booleans only, never values/config/status is the fastest way to see which integrations an instance
actually has configured — which is usually the difference between “it is broken”
and “it was never configured”.