{"slug": "stop-cursor-from-running-prisma-migrate-reset-on-the-wrong-database", "title": "Stop Cursor from running prisma migrate reset on the wrong database", "summary": "A developer published a Cursor rule file designed to stop AI coding agents from running destructive Prisma commands like `prisma migrate reset --force` against the wrong database. The rule, installed at `.cursor/rules/migration-checklist.mdc`, forces the agent to verify the target environment, review generated SQL for destructive operations, and confirm backups before any migration or push. The author notes Prisma 6.15.0 added an agent-detection consent gate for `migrate reset`, but recommends removing production credentials from the editor's `.env` and revoking DROP rights as a more reliable safeguard.", "body_md": "Here is the failure mode, step by step.\n\n`db push` to try something.`prisma migrate dev`, which reports drift and says the database needs a reset.` prisma migrate reset --force`.`.env` still has the staging or production `DATABASE_URL` you pasted in last week to debug something.\n`migrate reset` drops the database (or schema), recreates it and applies every migration. On Prisma 6 and earlier it also runs your seed. On dev that's a fine way to get unstuck. Anywhere else it's a restore-from-backup afternoon.\n\n`postgresql://app@db.internal:5432/app` says \"this one has customers in it.\"`--force`.\nSince Prisma ORM 6.15.0, the CLI looks for environment variables that coding agents set (for Cursor, `CURSOR_AGENT`). When it finds one, `prisma migrate reset` stops with an error telling the agent to explain what it was about to do and ask you first. The agent can only rerun it with `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION` set to the exact text of your consent message. The same check covers `prisma db push --force-reset`, and since 7.9.0, `prisma db push --accept-data-loss`. That is a good backstop. It still leaves gaps:\n\n`db execute`, or Drizzle.` migrate deploy`.\nYou want the agent checking the target before it reaches that prompt.\n\nThe cheapest fix isn't a rule. Don't keep prod or staging URLs in the `.env` your editor loads, and give your day-to-day role no `DROP` rights on shared databases. Rules steer the agent. Missing credentials can't be talked around.\n\nCursor loads project rules from `.cursor/rules/*.mdc`. Each file is markdown with a small frontmatter block:\n\n`description`: what the rule is for.` globs`: file patterns that pull the rule in.` alwaysApply`: `true` attaches it to every agent request.\nInstall:\n\n```\nmkdir -p .cursor/rules\n# save the rule below as .cursor/rules/migration-checklist.mdc\n```\n\nThen open Customize in the sidebar, go to Rules, and confirm it's listed. Test with \"migrations are out of sync, reset the db.\" A working setup asks about the target database instead of running a command.\n\nHere is the full rule. It's one of four in our Schema Migration Guard pack, and this one is free. Copy it as is or trim what you don't need.\n\n```\n---\ndescription: \"Pre-push and pre-migrate checklist for database schema changes\"\nglobs: [\"**/migrations/**\", \"**/prisma/migrations/**\", \"**/drizzle/**\"]\nalwaysApply: true\n---\n\n# Migration Checklist\n\n## PRE-MIGRATION CHECKLIST\n\nBefore running any migration command, verify:\n\n### 1. Environment Check\n- [ ] **Which database am I targeting?** (dev/staging/prod)\n- [ ] **Is this the correct connection string?** Check `DATABASE_URL` or config\n- [ ] **Do I have a backup?** (Required for staging/prod)\n\n### 2. Schema Review\n- [ ] **Did I read the generated SQL?** (Not just the schema diff)\n- [ ] **Are there destructive operations?** (DROP, TRUNCATE, DELETE)\n- [ ] **Will existing data survive?** (Type changes, NOT NULL additions)\n- [ ] **Are indexes appropriate?** (Not missing, not excessive)\n\n### 3. Data Considerations\n- [ ] **Will this migration lock tables?** (Large tables = long locks)\n- [ ] **Is there a data migration needed?** (Backfill, transform)\n- [ ] **What's the rollback plan?** (Reverse migration or restore)\n\n## PRE-PUSH CHECKLIST\n\nBefore pushing migration files to the repository:\n\n### 1. File Hygiene\n- [ ] **Migration file is committed** (Not in .gitignore)\n- [ ] **Migration name is descriptive** (Not \"migration_1\" or \"fix\")\n- [ ] **No sensitive data in migration** (No hardcoded credentials)\n- [ ] **SQL is reviewed and correct** (Read the actual file)\n\n### 2. Local Verification\n- [ ] **Migration applies cleanly locally** (Tested on fresh DB)\n- [ ] **App still works after migration** (Run tests)\n- [ ] **Migration is idempotent or guarded** (Won't fail if run twice)\n\n### 3. Team Coordination\n- [ ] **No conflicting migrations from teammates** (Pull latest first)\n- [ ] **Migration order is correct** (Timestamp/sequence is right)\n- [ ] **Breaking changes documented** (If API changes needed)\n\n## PRODUCTION DEPLOYMENT CHECKLIST\n\nBefore deploying migrations to production:\n\n### 1. Pre-Deploy\n- [ ] **Database backup completed** (Verified, not just scheduled)\n- [ ] **Maintenance window scheduled** (If needed for locks)\n- [ ] **Rollback plan documented** (Restore steps or reverse migration)\n- [ ] **Team notified** (On-call aware of deployment)\n\n### 2. During Deploy\n- [ ] **Monitor migration progress** (Watch for locks, errors)\n- [ ] **Check application health** (Errors, latency spikes)\n- [ ] **Have rollback ready** (Don't walk away mid-migration)\n\n### 3. Post-Deploy\n- [ ] **Verify migration status** (`migrate status` shows clean)\n- [ ] **Test affected features** (Not just \"app starts\")\n- [ ] **Monitor for delayed issues** (Slow queries, missing data)\n\n## DESTRUCTIVE OPERATION ESCALATION\n\nWhen a migration contains destructive SQL:\n\n### Level 1: Column Drop\n**Required:** Read SQL twice, confirm column name, verify no app references.\n```\nMigration contains: ALTER TABLE \"users\" DROP COLUMN \"legacy_field\"\nConfirm: \"I verified no code references legacy_field. Drop it.\"\n```\n\n### Level 2: Table Drop\n**Required:** Level 1 + verify no foreign keys, confirm data is backed up or worthless.\n```\nMigration contains: DROP TABLE \"temp_imports\"\nConfirm: \"I verified temp_imports has no important data and no references. Drop it.\"\n```\n\n### Level 3: Data Deletion\n**Required:** Level 2 + explicit row count awareness, backup verification.\n```\nMigration contains: DELETE FROM \"audit_logs\" WHERE created_at < '2023-01-01'\nConfirm: \"I understand this deletes ~50,000 rows. Backup verified. Proceed.\"\n```\n\n### Level 4: Full Reset\n**Required:** All above + explicit database name confirmation.\n```\nCommand: prisma migrate reset / drizzle-kit push --force\nConfirm: Type the database name to confirm: ___________\n```\n\n## COMMON MISTAKES TO CATCH\n\n### Prisma-Specific\n- `migrate dev` on non-dev database\n- Editing migration SQL after it's been applied elsewhere\n- `@@map` or `@map` changes that rename without data migration\n- Enum changes that remove values still in use\n\n### Drizzle-Specific\n- `push` instead of `generate` + `migrate` on persistent DB\n- Missing `NOT NULL` default for existing rows\n- `drizzle-kit drop` on migration that's already deployed elsewhere\n- Introspect overwriting intentional schema divergence\n\n### Universal\n- Changing column type without considering data truncation\n- Adding unique constraint to column with duplicate data\n- Removing column that's still referenced in app code\n- Deploying migration before code that handles new schema\n\n## ROLLBACK REFERENCE\n\n### Prisma Rollback Options\n``` bash\n# Mark migration as rolled back (doesn't undo DB changes)\nprisma migrate resolve --rolled-back [migration_name]\n\n# Actual rollback requires manual SQL or restore\npg_restore -d mydb backup.dump\n```\n\n### Drizzle Rollback Options\n``` bash\n# No built-in rollback: write reverse migration\ndrizzle-kit generate  # Create new migration to undo\n\n# Or restore from backup\npg_restore -d mydb backup.dump\n```\n\n## QUICK COMMANDS REFERENCE\n\n### Prisma\n``` bash\nprisma migrate status          # Check pending migrations\nprisma migrate dev             # Dev: generate + apply\nprisma migrate deploy          # Prod: apply pending only\nprisma migrate diff            # Preview changes\nprisma migrate resolve         # Fix migration state\n```\n\n### Drizzle\n``` bash\ndrizzle-kit status             # Check state\ndrizzle-kit generate           # Generate SQL files\ndrizzle-kit migrate            # Apply migrations\ndrizzle-kit push               # Direct push (dev only)\ndrizzle-kit introspect         # Generate schema from DB\nThe part doing the work for `migrate reset` is **Level 4: Full Reset**: the agent has to name the database first. The rest keeps it reading generated SQL instead of trusting the schema diff, which is where dropped columns hide. Commit `.cursor/rules/` so the whole team gets it.\n\nWith Drizzle the risky command is usually `drizzle-kit push`. It applies your schema straight to the database with no migration file, and `--force` auto-approves data-loss statements. That's fine against a throwaway local database. Against anything persistent, use the tracked flow:\n\n```\ndrizzle-kit generate   # writes SQL to your migrations folder\n# read the SQL\ndrizzle-kit migrate    # applies it\n```\n\nAlso check `dbCredentials.url` in `drizzle.config.ts`. If it reads `process.env.DATABASE_URL`, it has the same \"which `.env` is loaded?\" problem. The checklist above already matches `**/drizzle/**` and flags `push` on a persistent database.\n\nA rule is prose, so a determined agent can still ignore it. For a hard stop, add a Cursor hook. Project hooks live in `.cursor/hooks.json`, and a `beforeShellExecution` hook runs before each shell command the agent wants to execute. Its `matcher` is a regex tested against the full command string:\n\n```\n{\n  \"version\": 1,\n  \"hooks\": {\n    \"beforeShellExecution\": [\n      {\n        \"command\": \".cursor/hooks/block-destructive.sh\",\n        \"matcher\": \"migrate reset|--force-reset|--accept-data-loss|drizzle-kit push.*--force\"\n      }\n    ]\n  }\n}\n```\n\nThe script only runs for matching commands, so it can simply refuse:\n\n``` bash\n#!/bin/bash\n# .cursor/hooks/block-destructive.sh\ncat > /dev/null\nexit 2\n```\n\nMake it executable with `chmod +x .cursor/hooks/block-destructive.sh`. Exit code 2 blocks the command, the same as returning `\"permission\": \"deny\"` in the hook's JSON output. Other non-zero exit codes fail open and let the command through, and project hooks only run in a trusted workspace. Run those commands yourself, in your own terminal, when you mean it.\n\nWritten with AI assistance and checked against the Prisma and Cursor docs.\n\nDisclosure: Schema Migration Guard is our paid pack. It adds Prisma, Drizzle, and destructive-SQL review rules on top of this checklist: [https://labyrinth63.gumroad.com/l/kbhasc?utm_source=devto&utm_medium=organic&utm_campaign=guard_v2](https://labyrinth63.gumroad.com/l/kbhasc?utm_source=devto&utm_medium=organic&utm_campaign=guard_v2)", "url": "https://wpnews.pro/news/stop-cursor-from-running-prisma-migrate-reset-on-the-wrong-database", "canonical_source": "https://dev.to/labyrinthlab/stop-cursor-from-running-prisma-migrate-reset-on-the-wrong-database-3pch", "published_at": "2026-10-08 13:15:03+00:00", "updated_at": "2026-10-08 13:21:04.039546+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["Cursor", "Prisma", "Drizzle"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/stop-cursor-from-running-prisma-migrate-reset-on-the-wrong-database", "markdown": "https://wpnews.pro/news/stop-cursor-from-running-prisma-migrate-reset-on-the-wrong-database.md", "text": "https://wpnews.pro/news/stop-cursor-from-running-prisma-migrate-reset-on-the-wrong-database.txt", "jsonld": "https://wpnews.pro/news/stop-cursor-from-running-prisma-migrate-reset-on-the-wrong-database.jsonld"}}