Skip to content
Latchkey

Neon migrations run against the wrong branch in CI

The point of a branch per PR is to run migrations against an isolated copy. If the migration step reads the production DATABASE_URL instead of the branch URL, it either mutates main or fails against schema it should not touch.

What this error means

Migrations succeed but the changes land on the main branch, or a migration fails with unexpected existing objects, because the step used the wrong connection string.

migrate
Applying migration 0007_add_orders...
ERROR: relation "orders" already exists
(migration ran against main, not the fresh pr-123 branch)

Common causes

The migration step used the default DATABASE_URL

A repository secret DATABASE_URL points at main. The migration step never overrode it with the per-PR branch string, so it targeted production.

The branch URL was set after the migration step

Ordering put the connection-string derivation after the migrate step, so migrate saw the old value.

How to fix it

Export the branch URL before migrating

  1. Create the branch, then derive its connection string.
  2. Export that value as DATABASE_URL for the migrate step.
  3. Run migrations, then tests, all against the branch.
Terminal
URL=$(neonctl connection-string "pr-${{ github.event.number }}" \
  --project-id "$NEON_PROJECT_ID" --pooled)
echo "DATABASE_URL=$URL" >> "$GITHUB_ENV"
npm run migrate

Assert the branch before applying

Fail fast if the connection string still points at main so a misconfiguration cannot mutate production.

Terminal
neonctl branches get "pr-${{ github.event.number }}" --project-id "$NEON_PROJECT_ID" >/dev/null

How to prevent it

  • Derive and export the branch connection string before the migrate step.
  • Never point CI migrations at the shared main DATABASE_URL.
  • Verify the branch exists before running migrations against it.

Frequently asked questions

What causes "Neon migrations hit the wrong branch"?
A repository secret DATABASE_URL points at main. The migration step never overrode it with the per-PR branch string, so it targeted production.
How do I fix Neon migrations hit the wrong branch?
Export the branch URL before migrating

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card