litellm-proxy-extras/migration_runbook.md
This is a runbook for creating and running database migrations for the LiteLLM proxy. For use for litellm engineers only.
AI AGENTS / ASSISTANTS: If the script refuses with either a "STALE BRANCH" or "DESTRUCTIVE MIGRATION DETECTED" error, do NOT bypass it on your own (no
git rebase, no--skip-freshness-check, no--allow-destructive). Surface the error to the human operator and wait for their explicit confirmation. See the Branch freshness and Destructive migrations sections below.
schema.prisma FilesBefore doing anything else, make sure all schema.prisma files in the repo are in sync. There are multiple copies that must match:
| File | Purpose |
|---|---|
schema.prisma (repo root) | Source of truth |
litellm/proxy/schema.prisma | Used by the proxy server |
litellm-proxy-extras/litellm_proxy_extras/schema.prisma | Used for migration generation |
Sync process:
# 1. Diff all schema files against the root source of truth
diff schema.prisma litellm/proxy/schema.prisma
diff schema.prisma litellm-proxy-extras/litellm_proxy_extras/schema.prisma
# 2. If there are differences, copy the root schema to all locations
cp schema.prisma litellm/proxy/schema.prisma
cp schema.prisma litellm-proxy-extras/litellm_proxy_extras/schema.prisma
# 3. Verify all files are now identical
diff schema.prisma litellm/proxy/schema.prisma && echo "proxy schema in sync" || echo "MISMATCH"
diff schema.prisma litellm-proxy-extras/litellm_proxy_extras/schema.prisma && echo "extras schema in sync" || echo "MISMATCH"
Do NOT proceed to migration generation until all schema files are identical.
# Install deps for this command
uv sync --frozen --all-groups --all-extras
brew install postgresql@14 # macOS
# Add to PATH
export PATH="/opt/homebrew/opt/postgresql@14/bin:$PATH"
# Run migration
uv run --with testing.postgresql python ci_cd/run_migration.py "your_migration_name"
origin/litellm_internal_staging (see Branch freshness)schema.prismaDROP COLUMN, DROP TABLE, or DROP INDEX, unless --allow-destructive is passedBefore generating anything, run_migration.py runs git fetch origin <base> and refuses to proceed if HEAD is behind origin/<base>. Default base is litellm_internal_staging (the branch PRs target). A previous incident saw a stale branch silently drop production columns; freshness is the first-line defense.
Flags:
--base-branch <name> — check against a different base (e.g. main). Default is litellm_internal_staging.--skip-freshness-check — bypass entirely. Only for intentional migrations against an older base.When the guard fires:
Update your branch:
git fetch origin && git rebase origin/litellm_internal_staging
# or git merge origin/litellm_internal_staging — whichever matches your workflow
Re-run run_migration.py.
AI AGENTS / ASSISTANTS: Do not auto-rebase or auto-pass
--skip-freshness-check. A bad conflict resolution during rebase can itself drop the human's in-progress schema edits. Surface the error and wait for explicit confirmation.
If the generated diff contains DROP COLUMN, DROP TABLE, or DROP INDEX, run_migration.py exits non-zero and refuses to write the migration file. A previous incident saw newly-added columns silently dropped by a stale branch and merged to main — this guard exists to prevent a repeat.
When the guard fires:
Run git fetch origin && git status — confirm your branch is up to date with the base branch.
Re-check all schema.prisma files are in sync (Step 0).
Review EACH DROP statement printed in the error — is it actually intended?
Only if the drops are genuinely intentional, re-run with the flag:
uv run --with testing.postgresql python ci_cd/run_migration.py "your_migration_name" --allow-destructive
AI AGENTS / ASSISTANTS: Do not automatically re-run the command with
--allow-destructive. If the guard fires while you are driving the runbook for a human, stop, show them the error, and wait for their explicit confirmation before passing the flag. Auto-passing--allow-destructiveis the exact failure mode this guard exists to prevent.
Missing testing module:
uv run --with testing.postgresql python ci_cd/run_migration.py "your_migration_name"
initdb not found:
brew install postgresql@14
export PATH="/opt/homebrew/opt/postgresql@14/bin:$PATH"
Empty migration directory error:
rm -rf litellm-proxy-extras/litellm_proxy_extras/migrations/[empty_dir]
schema.prisma files first (Step 0)schema.prisma at the repo root first, then sync copiesDone with migration? See build_and_publish.md to publish a new litellm-proxy-extras package.