Django MigrationConflictError: multiple leaf nodes
Resolve Django migration conflicts when two branches add migrations with the same parent, producing multiple leaf nodes and a blocked migrate.
Symptoms
- CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph
- makemigrations refuses to run until the conflict is resolved
- Two developers each created a migration numbered 0007 on separate branches
Possible causes
- Two branches generated migrations from the same parent revision
- A merge brought in migrations that both descend from one node
- Squashed migrations were reintroduced inconsistently
- Manual migration files edited the dependency graph incorrectly
Diagnosis steps
List the conflicting leaves
python manage.py showmigrations --planInterpretation
The output shows which app has two leaf nodes sharing a dependency.
Locate the duplicate-numbered migrations
ls app/migrations/Interpretation
Two files with the same index derived from the same parent confirm the conflict.
Inspect dependencies declared in each file
Interpretation
The dependencies list shows the shared parent, which is what the merge must resolve.
Root cause
Django applies migrations as a graph and requires a single leaf per app. When independent branches each create a migration from the same parent and are merged, the app ends up with two branches and two leaves. Django refuses to guess an order and blocks further migrations.
Fix
Run `python manage.py makemigrations --merge` to create a merge migration that depends on both leaves, or manually rewrite one migration to depend on the other and renumber it. Commit the merge migration and ensure all branches pull it before generating new migrations.
Verify the fix
Run `python manage.py showmigrations --plan`; a single leaf remains, then `python manage.py migrate` applies cleanly with no conflict error.
Symptoms
Django stops with Conflicting migrations detected; multiple leaf nodes in the migration graph. makemigrations and migrate both refuse until the graph is linearised.
Diagnosis
Inspect the plan and the migration files:
python manage.py showmigrations --plan
ls myapp/migrations
Two files with the same index that share a parent node confirm the conflict.
Fix
Let Django build a merge migration:
python manage.py makemigrations --merge
python manage.py migrate
The generated file depends on both leaves. Commit it immediately so every branch shares one leaf.
Verification
Re-run showmigrations --plan; exactly one leaf remains per app, and migrate completes without the conflict error.
Avoiding the Conflict Next Time
The conflict is a collaboration problem as much as a database one. Merge migrations on the branch that lands second, and regenerate makemigrations immediately after every rebase so the graph stays linear. In CI, run python manage.py makemigrations --check --dry-run; it fails the build when committed model code and migration files disagree, which catches both missing and out-of-date migrations before they reach the shared branch. Squashing old migrations also helps, but only do it on migrations that no other open branch still depends on, or you reintroduce the same multiple-leaf state.