Two ORMs pointed at the same database produce split-brain writes: Prisma and Drizzle cache query results differently, generate non-equivalent SQL for identical model intent, and maintain independent connection pools that break transaction isolation. Concurrent writes through both clients can bypass each other's query-level constraints and leave rows in states neither ORM expected, corrupting production data and making debugging nearly impossible because neither stack trace sees the whole picture.
Critical because split-brain data layers silently corrupt production rows and create debugging dead ends that cost days to untangle.
Pick one ORM and migrate every file off the other. Inventory the damage first with grep -rl "from '@prisma/client'" src/ and grep -rl "from 'drizzle-orm'" src/, then port the smaller side to the survivor. Once imports are zero, run npm uninstall drizzle-orm drizzle-kit (or the Prisma equivalent). If you genuinely need two databases, isolate each ORM to its own connection file like src/db/legacy-pg.ts and document the boundary so no future commit crosses it.
ID: ai-slop-code-drift.data-auth-drift.dual-orm
Severity: critical
What to look for: Apply the three-condition rule against this exact ORM allowlist: prisma, @prisma/client, drizzle-orm, typeorm, sequelize, mongoose, kysely, @mikro-orm/core, objection, bookshelf. (@prisma/client and prisma count as a single ORM.) Before evaluating, extract and quote the exact package names found in package.json dependencies matching the allowlist. Count all libraries that meet all three conditions (at least 1 non-escape-hatch importing file). Report the file count for each.
Detector snippet (shell-capable tools only): If the tool has shell access, list every source file that imports one of the allowlisted ORMs. Group the output by ORM, count distinct files per ORM, and report any ORM with ≥1 importing file as "active." If rg is not installed or exits ≥2, fall back to the prose reasoning above.
rg -l -e "from ['\"]@prisma/client" -e "from ['\"]drizzle-orm" -e "from ['\"]typeorm" -e "from ['\"]sequelize" -e "from ['\"]mongoose" -e "from ['\"]kysely" src/
Pass criteria: 0 or 1 ORMs from the allowlist are actively used (meet all three conditions). When 1 ORM is found, quote the canonical ORM name and report: "Canonical ORM: [name] ([N] importing files)."
Fail criteria: 2 or more ORMs from the allowlist meet all three conditions in the same project — split-brain data layer that risks data inconsistency.
Do NOT pass when: Two ORMs are present, one is "actively migrating away" but BOTH still have active imports in production code paths. The risk is real until the migration is complete.
Skip (N/A) when: 0 ORMs from the allowlist appear in RUNTIME_DEPS (project is ORM-free, e.g., uses raw SQL or no database).
Cross-reference: For deeper schema and migration safety analysis, the Database Design & Operations audit (database-design-operations) covers ORM-specific concerns.
Detail on fail: "2 active ORMs detected: 'prisma' (12 importing files) AND 'drizzle-orm' (8 importing files). Two ORMs against the same database creates split-brain state."
Remediation: Two ORMs against the same database is a recipe for data inconsistency — they cache differently, generate different SQL, and won't share connection pools. Pick one and consolidate:
# Inventory which files import each ORM
grep -rl "from '@prisma/client'" src/
grep -rl "from 'drizzle-orm'" src/
# Migrate the smaller side to the larger one, then remove the loser:
npm uninstall drizzle-orm drizzle-kit
If you legitimately need two databases, isolate each ORM to its own database connection and document the boundary in code (e.g., src/db/legacy-pg.ts vs src/db/main-mongo.ts).