Common issues
The most common problems come from configuration that does not match what the
composed code expects. notewright doctor catches most of them before deploy;
this page covers the rest.
The scaffolded entry does not compile
Section titled “The scaffolded entry does not compile”This is expected. The generated src/index.ts has non-compiling holes where you
compose your providers. It will not compile until you install your provider
packages and wire them into defineApp. See Quick start.
Extraction does nothing / AI Gateway errors
Section titled “Extraction does nothing / AI Gateway errors”The follow-up pipeline reads AI_GATEWAY_ID, AI_GATEWAY_ACCOUNT_ID, and
AI_GATEWAY_TOKEN and fails fast if any is missing or blank.
- Confirm all three are set, and that
AI_GATEWAY_TOKEN(a secret) was included in your--secrets-fileat deploy. - Confirm the Anthropic key is stored in the gateway (BYOK) and the token has Run permission.
- Run
notewright doctorto confirm required vars declared in the fragment are present inwrangler.jsonc.
See AI Gateway setup.
notewright doctor will not run
Section titled “notewright doctor will not run”Doctor requires Bun. The CLI imports your TypeScript entry directly, which pulls
in agents and cloudflare: modules that plain Node cannot load. Install Bun
1.3.14+ and run under Bun. Node-only environments cannot run doctor.
Schedules are missing after deploy
Section titled “Schedules are missing after deploy”A Durable Object only registers its cron on first start. After a fresh deploy, run
notewright start (or call /health per agent) so each onStart() runs, then
confirm with notewright schedules. See Syncing & backfill.
D1 migrations not applied
Section titled “D1 migrations not applied”If doctor reports local migration files that are not applied, run the command it prints:
bunx wrangler d1 migrations apply <db> --remoteUse notewright doctor --check-remote to compare the remote d1_migrations table
against your local files.
Durable Object binding or migration mismatch
Section titled “Durable Object binding or migration mismatch”If doctor reports missing or extra DO bindings or migrations, your composed
providers and wrangler.jsonc disagree. wrangler.jsonc is the canonical source;
re-derive the build fragment from it rather than hand-editing the fragment. The
core bindings (FOLLOW_UP_AGENT/v2, SPEAKER_CONTEXT_AGENT/v3) and the
Granola provider’s GRANOLA_SYNC_AGENT/granola-v1 must all be present. See
Durable Objects.
CLI cannot find an instance or secret
Section titled “CLI cannot find an instance or secret”The connection resolver needs one of: --url + a secret, NOTEWRIGHT_URL +
NOTEWRIGHT_SECRET, or a linked instance with a keychain secret. If you see “no
instance to target”, run notewright login <url> or pass --url/--secret. See
the CLI overview.
Keychain unavailable
Section titled “Keychain unavailable”On platforms without a native keychain binding, the CLI falls back to a plain JSON
file next to config.json. To force that fallback (for example in CI), set
NOTEWRIGHT_DISABLE_KEYCHAIN=1.
401 Unauthorized from every endpoint
Section titled “401 Unauthorized from every endpoint”Every HTTP route is guarded by SYNC_SHARED_SECRET. A 401 means the bearer
token does not match the deployed secret; a 500 about an unconfigured secret
means the instance has no SYNC_SHARED_SECRET set. Re-check the secret you linked
with notewright login. See the HTTP API reference.