db schema declarative sync: no way to fail (non-zero exit) when the generated migration is destructive
Maintainers usually reply within 1 day
Nobody has claimed this yet.
- #7037 by @milekv — closed without merging
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- cli
Research direction
Start at the pointer in apps/cli/src/commands/db/schema/declarative/sync/sync.handler.ts:538-547, where result.dropWarnings is printed to stderr; trace how flags are declared for the sync command and how exit codes are set elsewhere in the CLI. Add a --fail-on-destructive flag (and, if feasible, JSON output of the warnings) so the command returns a non-zero exit before writing the migration. Verify with the reproduction steps from the issue, checking echo "exit=$?" both with and without the flag, and look for existing tests around the sync handler.
Written by the indexing model from the issue text.
Description
Summary
supabase db schema declarative sync --no-apply prints Found destructive changes in schema diff. Please double check if these are expected: to stderr when the planned migration contains drops. It still writes the migration file and exits 0. CI jobs and scripted workflows cannot tell a destructive plan from a safe one without scraping the human-readable stderr text. --output-format json does not help either: this command prints no JSON.
Feature request: a flag such as --fail-on-destructive, or a distinct non-zero exit code, that makes sync fail when the plan contains destructive changes. Ideally the flag would also skip writing the migration file. Including the drop warnings in --output-format json would also help.
Environment
- Supabase CLI 2.119.0 (npm package, darwin-arm64), bundled
@supabase/pg-delta1.0.0-alpha.56 - Postgres 17.11 (
public.ecr.aws/supabase/postgres:17.11.0.002) - macOS 26 (Darwin 25.3.0, arm64)
Steps to reproduce
-
supabase init, then add one migration:CREATE TABLE public.d (id int); -
Run:
supabase start supabase db reset --local supabase db schema declarative generate --local --overwrite rm supabase/schemas/public/tables/d.sql supabase db schema declarative sync --no-apply; echo "exit=$?"
Expected
A supported way to make this run fail on a destructive plan, either through an opt-in flag or a dedicated exit code, so a pipeline can stop before a drop is committed.
Actual
Applying migration 20260101000007_table.sql...
Generated migration SQL:
DROP TABLE "public"."d";
Created new migration at supabase/migrations/20261006190533_declarative_sync.sql
Found destructive changes in schema diff. Please double check if these are expected:
DROP TABLE "public"."d"
exit=0
supabase db schema declarative sync --no-apply --output-format json gives the same plain-text output and also exits 0.
Impact
Sync runs unattended (in CI, a pre-commit check, or an agent loop) and sees exit code 0. A schema file that was deleted or moved by mistake therefore becomes a committed DROP TABLE migration without any gate. The warning already exists. It just cannot be acted on programmatically.
Pointer
In the v2.119.0 tag (c66274cc6dc278a9413a6b0f099367ce150555ac), apps/cli/src/commands/db/schema/declarative/sync/sync.handler.ts:538-547 prints result.dropWarnings to stderr after the migration file is written. Execution then continues to the apply decision, and nothing changes the exit status. result.dropWarnings already has the data a flag would need.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 531
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 351
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from supabase/cli
-
stack: the HTTP gateway closes idle keep-alive connections after 5 s, so a client whose event loop is blocked gets ECONNRESET (`fetch failed`) on its next requestPossibly taken @7ttp claimed this 6 days ago. Open🐛 Bug supabase/cli
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
supabase/cli#6975 · 1 assignee ·
Maintainers usually reply within 1 day
-
📘 Docs supabase/cli
Difficulty 1/5 Under an hour Newbie friendliness 88/100
supabase/cli#6974 · 1 comment ·
Maintainers usually reply within 1 day
-
🐛 Bug supabase/cli
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
stack: a database helper stays behind as a `Created` container when readiness times out mid-createPossibly taken @just-some-random-pal claimed this today. Open🐛 Bug open-for-contribution supabase/cli
Difficulty 3/5 1-2 days Newbie friendliness 18/100
Maintainers usually reply within 1 day
-
🐛 Bug supabase/cli
Difficulty 3/5 1-2 days Newbie friendliness 45/100
supabase/cli#7055 · 1 comment ·
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 1/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
core
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
vectorize-io/hindsight#5457 ·
Maintainers usually reply within 1 day
-
beginner friendly community contributions-welcome good first issue hacktoberfest help wanted testing up-for-grabs
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
lukilabs/beautiful-mermaid#160 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
rescript-lang/rescript-lang.org#1420 ·
Maintainers usually reply within 2 days