agent's D1 migration ran against local instead of remote: the --remote flag was dropped
Fixes the agent applying D1 migrations to the local database when it meant remote, because the --remote flag was dropped. Use when local and remote schemas diverge after an agent migration run. Not for migration SQL errors or journal conflicts.
TL;DR
Wrangler D1 commands default to local. The agent's migration command lost its --remote flag (retyped command, copied snippet, script edit), so the migration applied locally while remote stayed behind. Now local is ahead of remote. Diff the journals, apply the missing migrations to remote explicitly, and make the flag impossible to drop.
The query
agent's D1 migration ran against local instead of remote: the --remote flag was droppedUse this when
- Local and remote D1 schemas diverge after an agent run.
- The remote journal is missing migrations the local journal has.
- The migration log shows no --remote flag.
Not for
- Migration SQL errors (fix the SQL).
- Journal conflicts (separate fix).
- Intentional local-only migrations (not a bug).
Steps
Step 1: Diff the journals
npx wrangler d1 migrations list [db] --local
npx wrangler d1 migrations list [db] --remoteExpected result: the exact set of migrations applied locally but not remotely. That is the repair list.
Step 2: Apply the missing migrations to remote
Run the apply with --remote explicitly, for the missing set.
Expected result: remote catches up. The journals agree again.
Step 3: Verify the schemas match
Compare table lists on both sides.
Expected result: identical schemas. The divergence is fully repaired, not partially.
Step 4: Make the flag explicit and default-safe
Wrap migration commands in a script that requires an explicit environment argument (local or remote) and refuses to run without one.
Expected result: the bare default can never silently win again. Every invocation names its target.
Step 5: Add a pre-apply confirmation showing the target
Expected result: the agent states 'applying to REMOTE' (or LOCAL) and the journal target before executing. The human (or the log) can catch the mismatch.
Why it happens
'Local by default' is a safety feature for humans and a trap for agents: the agent retypes or regenerates the command and the flag falls off. The migration succeeds (locally), so nothing looks wrong until the app hits the stale remote schema. Silent success in the wrong place is worse than a loud failure.
Edge cases
- If the agent ALSO wrote data locally thinking it was remote, that data needs migrating too, not just the schema.
- The reverse (remote when local was intended) is rarer but more dangerous. The explicit-target wrapper prevents both.
- CI migration steps should hard-code --remote. No flag, no merge.
- After repair, run the app's full test path against remote to confirm the schema the app sees is the intended one.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_ngOduKGg51kROl89sHIU6g