Skip to content

Revision 1. A newer revision has replaced this one. Read the current revision (2). The evidence on this page is this revision’s own — it has not been carried forward from, or to, any other revision.

Fixing D1 "no such table" after a migration that seemed to run

Covers the two most common causes: applying a migration to the wrong local/remote target, and a Worker binding pointing at a different database_id than the one that was migrated. Does not cover a migration file that itself has a SQL error (that fails loudly at apply time, not later as "no such table"), or drift specifically caused by an ORM's own migration tracking — see the Drizzle-specific playbook for that.

Supersededno reproductions yetWhy this confidence?
Revision 1published by DevYou curation

Symptoms

The diagnostic path

8 steps, exactly as this revision published them.

  1. Step 1 · StartD1 query fails with "no such table"

    A SELECT/INSERT/UPDATE against a table fails as if it were never created, despite a migration existing for it.

    What happens next

    • passed step 2, Check which database the migration actually ran against
  2. Step 2 · TestCheck which database the migration actually ran against

    D1 local and remote are separate SQLite databases. wrangler d1 migrations apply needs an explicit --local or --remote flag, and running it once with one flag does not apply it to the other.

    Read-onlysh
    npx wrangler d1 migrations list <DATABASE_NAME> --remote

    Expected result

    The migration you expect is listed under migrations still to be applied, rather than under already-applied ones.

    What happens next

    • passed step 3, Apply the migration to the target that's missing it
    • failed step 4, Check whether the binding points at a different database
    • unknown step 3, Apply the migration to the target that's missing it
  3. Step 3 · FixApply the migration to the target that's missing it

    Run migrations apply against whichever target the failing query is actually hitting — typically --remote for a deployed Worker, --local for wrangler dev.

    Changes statesh

    Changes system or service state. Review before running.

    Applies any pending .sql migration files to the remote D1 database, creating or altering tables as those files specify. It does not delete existing data unless a migration file itself contains a DROP or DELETE statement.

    npx wrangler d1 migrations apply <DATABASE_NAME> --remote

    What happens next

    • passed step 5, Confirm the table exists where you're querying it
  4. Step 4 · TestCheck whether the binding points at a different database

    Confirm the database_id your deployed Worker is actually bound to matches the one you migrated — a stale preview_database_id, or a staging/production database_id mix-up in wrangler.jsonc, will produce exactly this symptom even after a correct migration run.

    Read-onlysh
    npx wrangler d1 info <DATABASE_NAME>

    Expected result

    The database_id shown does not match the database_id in the d1_databases block your Worker is deployed with.

    What happens next

    • passed step 6, Point the binding at the correct database and redeploy
    • failed step 7, Not a target/binding mismatch — escalate
    • unknown step 7, Not a target/binding mismatch — escalate
  5. Step 5 · Verify the fixConfirm the table exists where you're querying it

    List the tables directly against the same target (local/remote) your Worker queries at runtime.

    Read-onlysh
    npx wrangler d1 execute <DATABASE_NAME> --remote --command "SELECT name FROM sqlite_master WHERE type='table';"

    Expected result

    The table you expected appears in the result set.

    What happens next

    • passed step 8, Resolved
    • failed step 7, Not a target/binding mismatch — escalate
    • unknown step 7, Not a target/binding mismatch — escalate
  6. Step 6 · FixPoint the binding at the correct database and redeploy

    Correct the database_id (and preview_database_id if relevant) in your Wrangler configuration to match the database that actually has the migration applied, then redeploy.

    Changes statesh

    Changes system or service state. Review before running.

    Redeploys the Worker so it binds to the D1 database that has the migration applied. No data in either database is modified by this step.

    npx wrangler deploy

    What happens next

    • passed step 5, Confirm the table exists where you're querying it
  7. Step 7 · EndNot a target/binding mismatch — escalate

    If the migration is applied to the right database and the binding is correct, check whether migrations_table was customised away from the default and the table really was created but under a name or in a way you're not querying — or check the migration file itself for a typo in the table name.

  8. Step 8 · EndResolved

    The correct database has the migration applied and the Worker is bound to that database; the query now succeeds.

Sources

Why this confidence?

This counts only what was recorded against revision 1 itself. Nothing reported against another revision is included here — see the revision history for why.