prisma/prisma · error
PLANNING_FAILED
PLANNING_FAILED
Error message
Migration planning failed due to conflicts
What it means
Returned by `db init` / `db update` when mapPlannerError receives a PlannerError of kind `planFromDiffFailed` (db-run.ts:333-345). The migration planner could not produce a plan from the diff between the live database marker state and the target contract; the `conflicts` array enumerates the specific blockers. This is a hard planning failure — no operations are produced, so nothing is applied.
Source
Thrown at packages/1-framework/3-tooling/cli/src/control-api/operations/db-run.ts:335
: `Orphan contract-space markers detected for ${orphans.length} spaces`;
return new CliStructuredError('MIGRATION.CONTRACT_SPACE_VIOLATION', summary, {
why: `The database has \`_prisma_marker\` rows for spaces (${orphans
.map((s) => `"${s}"`)
.join(
', ',
)}) that are not declared in the project's \`extensions\`. The aggregate pipeline refuses to advance markers it cannot account for.`,
fix: 'Either re-declare the missing extension(s) in `extensions` (so the aggregate owns them again), or remove the orphan marker row(s) from `_prisma_marker` once you have confirmed the corresponding tables can be safely retired.',
docsUrl: 'https://pris.ly/contract-spaces',
meta: {
violations: orphans.map((spaceId) => ({ kind: 'orphanMarker', spaceId })),
},
});
}
function mapPlannerError(error: PlannerError): DbInitResult | DbUpdateResult {
if (error.kind === 'planFromDiffFailed') {
const failure: DbInitFailure | DbUpdateFailure = {
code: 'PLANNING_FAILED',
summary: 'Migration planning failed due to conflicts',
conflicts: error.conflicts,
why: undefined,
meta: undefined,
};
return blindCast<
DbInitResult | DbUpdateResult,
'notOk(failure) is shape-compatible with both DbInitResult and DbUpdateResult; the union is the return type of the surrounding function'
>(notOk(failure));
}
if (error.kind === 'extensionPathUnreachable') {
return buildRunnerFailure({
summary: `Cannot resolve apply path for extension space "${error.spaceId}"`,
why: `No path in the on-disk migration graph for extension space "${error.spaceId}" reaches the on-disk head ref hash "${error.target}".`,
meta: { spaceId: error.spaceId, target: error.target },
});
}
if (error.kind === 'extensionPathUnsatisfiable') {View on GitHub (pinned to 1243cdffbe)
Solutions
- Inspect `result.failure.conflicts[]` — each entry names the specific table/column/invariant and the conflict kind.
- Resolve each conflict, typically by authoring an explicit migration step or widening the schema change.
- Re-run in `mode: 'plan'` to preview the resolved diff before applying.
- If a marker is genuinely stale, reset it per the marker/contract-spaces docs only after confirming the DB actually matches the intended baseline.
- For type-narrowing conflicts, introduce an additive widening migration first, then narrow in a follow-up.
Example fix
// before — schema narrows Int -> String with no path
model User { id String @id } // was Int
// after — author an explicit widening migration edge first
// migration create -> produces a recorded edge the planner can replay,
// then narrow the column in the schema Defensive patterns
Strategy: validation
Validate before calling
// Run a plan-only pass first to surface planner conflicts before touching the database.
const plan = await client.dbUpdate({ ...opts, mode: 'plan' }); // or dbInit(..., { mode: 'plan' })
if (!plan.ok && plan.failure.code === 'PLANNING_FAILED') {
for (const c of plan.failure.conflicts ?? []) {
console.error(`${c.kind}: ${c.summary}${c.why ? ` — ${c.why}` : ''}`);
}
// resolve schema conflicts in the contract, then re-plan before any apply.
} Type guard
import type { DbUpdateResult, DbUpdateFailure } from '@prisma-next/cli/control-api';
const isPlanningFailed = (f: DbUpdateFailure): f is DbUpdateFailure & { code: 'PLANNING_FAILED'; conflicts: readonly MigrationPlannerConflict[] } =>
f.code === 'PLANNING_FAILED';
const result: DbUpdateResult = await client.dbUpdate(opts);
if (!result.ok && isPlanningFailed(result.failure)) {
const conflicts = result.failure.conflicts; // type-narrowed, non-undefined
} Prevention
- Always run mode: 'plan' (or the CLI --plan / dry-run) in CI and review warnings/conflicts before any apply reaches a database.
- Keep migrations linear and append-only; PLANNING_FAILED usually follows a non-additive schema change the planner cannot reconcile (type/nullability conflicts).
- When a conflict appears, fix it at the contract/schema source rather than hand-editing migration files.
When it happens
Trigger: Running `db init` or `db update` (plan or apply) where planMigration's diff yields conflicts — e.g., renaming a column the planner can't widen in place, narrowing a column type with no widening path, dropping a required invariant, or a marker hash the planner can't reason about.
Common situations: Editing a schema in a way the planner deems non-migratable in place; a stale `_prisma_marker` row pointing at a hash absent from the on-disk graph; switching a column type without an intermediate widening migration; conflicting changes merged from two branches.
Related errors
- RUNNER_FAILED
- RUNNER_FAILED
- MIGRATION.UNKNOWN_REF
- ${manifestPath}: not valid JSON (${error instanceof Error ?
- ${manifestPath}: manifest is not a JSON object
AI-assisted analysis of prisma/prisma@1243cdffbe (2026-08-01).
Data as JSON: /data/errors/3fd5b09a4be17b6a.json.
Report an issue: GitHub.