Repository navigation
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.
"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.
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.
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
createrule 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.
Castra is MIT licensed. Found a mistake on this page? Open an issue or start a discussion.