Skip to content

Troubleshooting

Search this page for the message you see.

The API checks its variables at startup and stops with Invalid environment variables:, followed by one line per problem.

Message Fix
AUTH_SECRET: must be at least 32 characters Generate one: openssl rand -base64 32
AUTH_SECRET: is still the example value; generate a real one for production Same, in production or production:up
Set AUTH_SECRET in .env. Generate one with openssl rand -base64 32 production:up found no AUTH_SECRET in .env
STRIPE_WEBHOOK_SECRET: is required with STRIPE_SECRET_KEY Run bun run billing:listen and put the whsec_… it prints in .env
POLAR_WEBHOOK_SECRET: is required with POLAR_ACCESS_TOKEN Add a webhook endpoint in Polar and put its secret in .env: Polar
BILLING_PROVIDER: is stripe, but POLAR_ACCESS_TOKEN is set (or the other way round) Set BILLING_PROVIDER to the provider whose key you set, and empty the other key
GOOGLE_CLIENT_SECRET: set both GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET, or neither You set one half of a provider
OTEL_EXPORTER_OTLP_HEADERS: must be name=value pairs, comma-separated Write it as x-honeycomb-team=abc123,other=value
MIXPANEL_TOKEN: must be a Mixpanel project token… Use the project token from the project’s settings, not its API secret or a service account
POSTHOG_KEY: must be a PostHog project API key (phc_…)… Use the project API key from the project’s settings, not a personal API key (phx_…)
ANALYTICS_PROVIDER: is mixpanel, but POSTHOG_KEY is set (or the other way round) Set ANALYTICS_PROVIDER to the provider whose key you set, and empty the other key
SENTRY_DSN: Invalid URL Copy the DSN from the project’s Settings > Client Keys: it starts with https://
[sentry-vite-plugin] Error while building the web app Source maps were not sent: check SENTRY_AUTH_TOKEN, SENTRY_ORG and SENTRY_WEB_PROJECT
STAND_INS: is for tests on this machine or in CI… It replaces Stripe and the model for the browser journeys. Leave it empty
STAND_INS: replaces Stripe, Polar and the model… The journeys run without real keys: docker-compose.acceptance.yml empties them
LOG_LEVEL: Invalid option Use fatal, error, warn, info, debug, trace or silent
Log lines Redis: connect ECONNREFUSED, or checks.redis is down Start Redis: bun run services:up. Elsewhere, check REDIS_URL
DATABASE_URL: Invalid URL, or the API can’t connect Start the database: bun run services:up
production:up fails on a port Something uses 8080, 8081 or 8026. Change it in docker-compose.production.yml
docker:dev fails with port is already allocated bun dev is running too. Stop one of them: they use the same ports
Message or symptom Fix
The verification email never arrives, locally It is in Mailpit, http://localhost:8025, not your inbox
Signing in leads to “Verify your email” The address isn’t verified. A new link was sent
“This link no longer works” Reset links work once, for an hour. Ask for a new one
401 Sign in to continue No session: signed out, or the cookie wasn’t sent
403 on every call to /api/auth The browser’s address is not WEB_URL or in CORS_ORIGINS
403 This account has been suspended… An admin suspended it. See Admin panel
429 Too many requests. Please try again later. The sign-in rate limit, in production
No Google or GitHub button One of its two values is missing, or the API wasn’t restarted
You are the only owner of … before deleting your account. Make someone else owner, or delete the workspace first
No Admin in the menu, or 403 Only admins can do this Your address isn’t in ADMIN_EMAILS or isn’t verified. Or you’re signed in as someone else: stop first
401 This API key is not valid… The key was revoked or has expired, or was copied wrong. Create a new one
403 API keys can only call the routes of their workspace. Keys reach /api/workspaces/<their workspace>/… only. See API keys
400 That URL is taken. Choose another. Another workspace has that address, or is being made with it at this moment: pick another
403 API keys cannot do this. Sign in to do it. The route is for people: it reads @CurrentUser() or is marked @NoApiKeys()
429 Too many requests with this API key… The key’s rate limit: wait the seconds in Retry-After
Log line Rate limiting could not determine a client IP The API gets no single visitor address. See Other hosts
Message or symptom Fix
Cannot reach the server The API is not running, or EXPO_PUBLIC_API_URL is wrong. On a phone, localhost is the phone
Signing in from the app answers 403 MOBILE_SCHEME is not the scheme in apps/mobile/app.json
Notifications are not set up for this build Run bunx eas-cli init in apps/mobile: see Mobile builds
Notifications need a real phone A simulator cannot receive them. Use a development build on a phone
Cannot find native module 'ExpoAsset' in Expo Go Expo was started for a build of your own. Use bun run dev:mobile, which starts it for Expo Go
A link to a new screen does not type-check Start bun run dev:mobile once: it writes the list of screens
Message or symptom Fix
The billing page says billing is not set up Set STRIPE_SECRET_KEY, or POLAR_ACCESS_TOKEN with BILLING_PROVIDER=polar
503 Stripe has no price "pro_month" Run bun run billing:sync
503 Polar has no product for pro, monthly Run bun run billing:sync with BILLING_PROVIDER=polar
Manage fails with Polar’s 403 insufficient_scope With teams on, the token needs read access to members: see Polar
You paid and the plan didn’t change The webhook didn’t arrive. Locally keep billing:listen running; in production check the endpoint in Stripe
400 Invalid webhook signature STRIPE_WEBHOOK_SECRET is from another endpoint, or test mode with a live key
402 … is part of the Pro plan. Upgrade to use it. The plan lacks that feature. See Charge for a feature
402 You have used the … included this month The free plan’s allowance is used up. See Charge for usage
402 You have used the … your plan includes until The plan has no price beyond its allowance (pricePerUnit: null)
503 Stripe has no price "pro_month_aiMessages" A plan charges for a meter that has no price yet. Run bun run billing:sync
Usage beyond the allowance is not on the invoice The subscription is older than the meter’s price. See Charge for usage
Log line usage.report … failed The provider refused the usage. The job retries for about a day; the error says why
409 This workspace already has a subscription Change plans in the customer portal, not by checking out again
400 This workspace has no billing account yet The portal exists once someone has started a checkout
Log line saying a price is not one of your plans Someone subscribed to a price made by hand in Stripe. Use the ones billing:sync made
Message or symptom Fix
email.send <id> failed (attempt 1 of 10): <reason> The mail server refused or was unreachable. It retries for about 2 hours
Sent "<subject>" to <address> but nothing arrives Your provider accepted it. Check its logs, and that MAIL_FROM’s domain is verified
Nothing is sent at all No worker is running. See Jobs below
No email "<subject>" was sent to <address> in a test Nothing matching was sent. t.outbox.emails() shows what was
Message or symptom Fix
The contact form is not set up. Set CONTACT_EMAIL on the API
You have sent several messages already. Try again in an hour. 5 messages an hour per address; wait, or restart the API while developing
The contact form answers 502 The site cannot reach the API: set API_URL on the site, or run the API while developing
A new page shares with no image Add it to pages in apps/site/src/lib/pages.ts
Message or symptom Fix
A job stays pending JOBS_WORKER=false and no bun run worker is running, or run_at is in the future
No handler for the job "…" No @OnJob() for it in a provider that is part of a module
Two handlers for the job "…". A job has exactly one. Two methods have @OnJob() for the same job
… failed (attempt 5 of 5) as an error It gave up. The reason is in last_error on its row in jobs
enqueue throws a ZodError The payload doesn’t match the job’s schema. Nothing was queued
A job ran twice It ran over 10 minutes or a worker died. Make handlers safe to repeat
Message or symptom Fix
503 AI is not set up. Add AI_GATEWAY_API_KEY to .env. Set the key and restart the API
The assistant could not answer. Try again in a moment. The gateway or model failed: wrong key, unknown model, no credit. The reason is in the API’s output
The answer arrives all at once Something between the API and the browser buffers it
Message or symptom Fix
There is no .env.railway yet. Create it with `bun run deploy:init`. Run bun run deploy:init
RAILWAY_PROJECT is not set in .env.railway. Write your project’s name there
RAILWAY_REPO is not set in .env.railway. This folder has no GitHub origin. Write owner/name there
This folder is linked to the Railway project "…" The wrong project is linked. Run bun run railway link
This version of railway/iac requires Railway CLI 5.42.1 or newer You ran your own older railway. Use bun run deploy:plan
Railway services are created, but never build Install Railway’s GitHub app with access to your repository, then connect each service: bun run railway service source connect --repo <owner/name> --branch main --service <name>
WEB_URL: Invalid URL in the API’s logs on Railway web has no address yet. Run bun run railway domain --service web --port 8080, then redeploy api
A push to your branch does not deploy Connect each service as above; recording the repository in the file is not enough
Every log line on your host shows as info Your host reads the level as a word. The kit writes "level":"warn" in production; a line with a number comes from something else
There is no .env.aws yet. Create it with `bun run deploy:init aws`. Run bun run deploy:init aws
Nothing was changed. Correct .env.aws, then run this again. A FAIL line above it says which setting. The same check runs alone as bun run deploy:check --before aws
… is empty in .env.railway (or .env.aws), as a note Fine if it is already set on the host. If not, the API will not start: fill it in
The migrations failed (exit 1), so nothing else was changed The version that was running still is. Read the migrations’ output in the CloudWatch stream the message names, fix the migration, and apply again
Unable to resolve AWS account to use or ExpiredToken The AWS CLI is not signed in. Run aws login, then the command again
ECS Service Linked Role is not ready The account had never used ECS. deploy:apply:aws now creates the role first; run it again
AWS: CREATE_FAILED on the certificate, or it waits for an hour The domains are not in AWS_HOSTED_ZONE’s zone, or that zone is not the one the domain’s registrar points at
AWS: the deploy waits on a service for a long time, then rolls back The new version never got healthy. Read its logs: aws logs tail <LogGroup> --log-stream-name-prefix api
AWS: 502 under /api, and lookup api … no such host in the web app’s logs The web app started before the API, so it never learned the name. Fixed in the stack; on a stack deployed before the fix, run aws ecs update-service --force-new-deployment for web and site
current credentials could not be used to assume …cdk-…-deploy-role… Harmless with the root account, which cannot assume roles: CDK uses your own credentials
A FAIL line from deploy:check It names what failed. Check the container’s logs
Links in emails point at the wrong address WEB_URL is wrong, or the API started before web had an address: redeploy api