Skip to content

Troubleshooting

Özer Özdaş edited this page Oct 11, 2026 · 1 revision

Troubleshooting

Error responses from the API are application/problem+json. Their type field links to a page that explains the error, for example not_found. Start there.

Deploy and token

"Invalid Cloudflare API token" with a cfat_... token. Account tokens are verified per account, so the CLI needs the account id. Set CLOUDFLARE_ACCOUNT_ID (or pass --account-id). Recent CLI versions tell you this before making any call.

multiple-accounts. The token sees more than one account, usually because All accounts was chosen. Set CLOUDFLARE_ACCOUNT_ID, or recreate the token scoped to one account.

"Global API Key is not supported". You copied the cfk_ Global API Key. Create a Custom token instead; see Deploying to Cloudflare.

pnpm deploy does something unexpected. pnpm deploy is pnpm's own command. Use pnpm run deploy.

A permission is missing. Run pnpm doctor. It is read-only and lists exactly which permission or binding is missing.

Local development

My new table answers 404. Tables are closed until castra.config.ts opens them. The Worker also reads the committed snapshot, not the live database. After adding a table, run pnpm db:migrate:local, then pnpm generate, then restart pnpm dev.

castra generate --check says tables are missing. It compares the snapshot with the local D1. A fresh checkout or a cleared .wrangler/ folder has an empty local database. Run pnpm db:migrate:local first.

Sign-up returns 403 INVALID_ORIGIN. Better Auth only trusts the origin of BETTER_AUTH_URL by default. Set trustedOrigins in src/index.ts to the origin you call from: http://localhost:8787 locally, and your real URL in production. Requests without an Origin header (curl, server-to-server) are accepted.

Every auth request fails with a generic 500, but /health is fine. BETTER_AUTH_SECRET is missing, too short (it needs at least 32 characters) or a placeholder. Generate one with openssl rand -base64 32. Put it in .dev.vars locally; on Cloudflare it is a Worker secret.

API responses

A create returns 403. One of three things:

  • You sent a server-set column (such as owner_id). Leave it out; Castra fills it in.
  • The create rule does not allow you.
  • The stored row would fall outside the policy (write_check_failed).

The type in the response tells you which.

403 unsafe_schema on every write to one table. The table has ON CONFLICT REPLACE, which would silently delete rows. Remove it in a migration. See unsafe_schema.

An include returns fewer children than expected. One-to-many includes are capped at 25 rows per parent in v0.1, and the response does not say so. Query the child table directly with a filter instead.

Still stuck? Ask in Discussions → Q&A. Include the problem type and the request, but never a token or secret.

Clone this wiki locally