Stop Cursor from running prisma migrate reset on the wrong database 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. Here is the failure mode, step by step. 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. 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. postgresql://app@db.internal:5432/app says "this one has customers in it." --force . Since 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: db execute , or Drizzle. migrate deploy . You want the agent checking the target before it reaches that prompt. The 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. Cursor loads project rules from .cursor/rules/ .mdc . Each file is markdown with a small frontmatter block: description : what the rule is for. globs : file patterns that pull the rule in. alwaysApply : true attaches it to every agent request. Install: mkdir -p .cursor/rules save the rule below as .cursor/rules/migration-checklist.mdc Then 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. Here 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. --- description: "Pre-push and pre-migrate checklist for database schema changes" globs: " /migrations/ ", " /prisma/migrations/ ", " /drizzle/ " alwaysApply: true --- Migration Checklist PRE-MIGRATION CHECKLIST Before running any migration command, verify: 1. Environment Check - Which database am I targeting? dev/staging/prod - Is this the correct connection string? Check DATABASE URL or config - Do I have a backup? Required for staging/prod 2. Schema Review - Did I read the generated SQL? Not just the schema diff - Are there destructive operations? DROP, TRUNCATE, DELETE - Will existing data survive? Type changes, NOT NULL additions - Are indexes appropriate? Not missing, not excessive 3. Data Considerations - Will this migration lock tables? Large tables = long locks - Is there a data migration needed? Backfill, transform - What's the rollback plan? Reverse migration or restore PRE-PUSH CHECKLIST Before pushing migration files to the repository: 1. File Hygiene - Migration file is committed Not in .gitignore - Migration name is descriptive Not "migration 1" or "fix" - No sensitive data in migration No hardcoded credentials - SQL is reviewed and correct Read the actual file 2. Local Verification - Migration applies cleanly locally Tested on fresh DB - App still works after migration Run tests - Migration is idempotent or guarded Won't fail if run twice 3. Team Coordination - No conflicting migrations from teammates Pull latest first - Migration order is correct Timestamp/sequence is right - Breaking changes documented If API changes needed PRODUCTION DEPLOYMENT CHECKLIST Before deploying migrations to production: 1. Pre-Deploy - Database backup completed Verified, not just scheduled - Maintenance window scheduled If needed for locks - Rollback plan documented Restore steps or reverse migration - Team notified On-call aware of deployment 2. During Deploy - Monitor migration progress Watch for locks, errors - Check application health Errors, latency spikes - Have rollback ready Don't walk away mid-migration 3. Post-Deploy - Verify migration status migrate status shows clean - Test affected features Not just "app starts" - Monitor for delayed issues Slow queries, missing data DESTRUCTIVE OPERATION ESCALATION When a migration contains destructive SQL: Level 1: Column Drop Required: Read SQL twice, confirm column name, verify no app references. Migration contains: ALTER TABLE "users" DROP COLUMN "legacy field" Confirm: "I verified no code references legacy field. Drop it." Level 2: Table Drop Required: Level 1 + verify no foreign keys, confirm data is backed up or worthless. Migration contains: DROP TABLE "temp imports" Confirm: "I verified temp imports has no important data and no references. Drop it." Level 3: Data Deletion Required: Level 2 + explicit row count awareness, backup verification. Migration contains: DELETE FROM "audit logs" WHERE created at < '2023-01-01' Confirm: "I understand this deletes ~50,000 rows. Backup verified. Proceed." Level 4: Full Reset Required: All above + explicit database name confirmation. Command: prisma migrate reset / drizzle-kit push --force Confirm: Type the database name to confirm: COMMON MISTAKES TO CATCH Prisma-Specific - migrate dev on non-dev database - Editing migration SQL after it's been applied elsewhere - @@map or @map changes that rename without data migration - Enum changes that remove values still in use Drizzle-Specific - push instead of generate + migrate on persistent DB - Missing NOT NULL default for existing rows - drizzle-kit drop on migration that's already deployed elsewhere - Introspect overwriting intentional schema divergence Universal - Changing column type without considering data truncation - Adding unique constraint to column with duplicate data - Removing column that's still referenced in app code - Deploying migration before code that handles new schema ROLLBACK REFERENCE Prisma Rollback Options bash Mark migration as rolled back doesn't undo DB changes prisma migrate resolve --rolled-back migration name Actual rollback requires manual SQL or restore pg restore -d mydb backup.dump Drizzle Rollback Options bash No built-in rollback: write reverse migration drizzle-kit generate Create new migration to undo Or restore from backup pg restore -d mydb backup.dump QUICK COMMANDS REFERENCE Prisma bash prisma migrate status Check pending migrations prisma migrate dev Dev: generate + apply prisma migrate deploy Prod: apply pending only prisma migrate diff Preview changes prisma migrate resolve Fix migration state Drizzle bash drizzle-kit status Check state drizzle-kit generate Generate SQL files drizzle-kit migrate Apply migrations drizzle-kit push Direct push dev only drizzle-kit introspect Generate schema from DB The 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. With 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: drizzle-kit generate writes SQL to your migrations folder read the SQL drizzle-kit migrate applies it Also 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. A 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: { "version": 1, "hooks": { "beforeShellExecution": { "command": ".cursor/hooks/block-destructive.sh", "matcher": "migrate reset|--force-reset|--accept-data-loss|drizzle-kit push. --force" } } } The script only runs for matching commands, so it can simply refuse: bash /bin/bash .cursor/hooks/block-destructive.sh cat /dev/null exit 2 Make 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. Written with AI assistance and checked against the Prisma and Cursor docs. Disclosure: 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