Skip to content

Broken Alembic migration chain: KeyError '20260216_002' — fresh-DB upgrade impossible #9759

Closed

Description

@mrveiss

Summary

The backend Alembic migration chain is broken: alembic upgrade head aborts with KeyError: '20260216_002' — a migration's down_revision references revision 20260216_002, which no file in autobot-backend/migrations/versions/ defines. The history has a gap, so migrations cannot be applied to a fresh database at all.

How found

Wiring RBAC-by-default for docker compose (umbrella #9720) requires bootstrapping the Postgres schema via alembic upgrade head. Against a fresh autobot_users DB it fails:

File ".../alembic/script/revision.py", line 245, in _revision_map
    down_revision = map_[downrev]
KeyError: '20260216_002'

Also found (fixed in #9720 branch)

migrations/env.py:get_url() read config.database_url / config.db_host off the Alembic Config object (which has no such attributes) → AttributeError, making migrations unrunnable even before the chain gap. Fixed there to read AUTOBOT_DATABASE_URL / AUTOBOT_POSTGRES_HOST from env. A second latent mismatch: env.py builds an async engine but get_url() falls back to postgres_sync_url (postgresql:// → psycopg2, not installed); async callers need postgresql+asyncpg://.

Impact

Fix needed

Locate the missing 20260216_002 revision (deleted/squashed?), repair the chain (restore the revision or re-point down_revisions), and verify alembic upgrade head applies cleanly end-to-end on a fresh Postgres. Then wire a one-shot alembic upgrade head step into the docker startup (init service or entrypoint) before the backend serves.

Activity

  1. mrveiss commented on Jun 8, 2026

    @mrveiss
    OwnerAuthor

    Update — root cause is deeper than a chain gap (full investigation)

    Attempting alembic upgrade head against a fresh Postgres surfaced four compounding faults. Fixed the first three in the #9720 branch; the fourth is architectural:

    1. ✅ env.py bug — get_url() read config.database_url/config.db_host off the Alembic Config object (no such attrs) → AttributeError. Fixed to read AUTOBOT_DATABASE_URL/AUTOBOT_POSTGRES_HOST.
    2. ✅ Revision-id mismatch — 20260216_003.down_revision = "20260216_002", but the secrets migration's id is the short "002" → KeyError. Re-pointed 003 to "002" (safe: down_revisions aren't stored in DBs).
    3. ✅ Three divergent heads (20260524_036b, 20260527_046, 20260604_051) — added merge migration 20260608_052_merge_heads.
    4. ❌ Incomplete fresh-DB schema bootstrap (architectural) — migration 002 runs ALTER TABLE secrets ADD COLUMN org_id, but no migration ever create_table('secrets'). secrets is a SQLAlchemy model (models/secret.py), created via metadata.create_all, not migrations. Lifespan only create_alls SkillsBase.metadata (Skills tables) — never user_management Base, LLCBase, or the secrets/secrets-owning metadata. So a fresh Postgres can be bootstrapped by neither alembic upgrade head (assumes pre-existing create_all tables) nor the current create_all (covers only Skills). Existing single-host DBs work only because they accreted tables over time.

    Real fix (proposed)

    Fresh-DB bootstrap should be: create_all over the full combined metadata (user_management Base + LLCBase + model Bases incl. secrets) then alembic stamp head (mark migrations applied without replaying history), wired as a one-shot docker startup step gated on postgres_enabled. Requires auditing every model Base for create_all coverage and confirming the create_all output matches head.

    Status

    RBAC-by-default (#9720) is blocked on this. All other out-of-box fixes are complete and verified healthy.

  2. mrveiss commented on Jun 10, 2026

    @mrveiss
    OwnerAuthor

    Bug sweep 2026-06-10 → TOO-BIG. Cross-cutting schema/migration repair (locate the missing 20260216_002 revision or re-point down_revisions, then prove alembic upgrade head applies clean on a fresh DB, plus wire a one-shot upgrade into docker startup). Blocks RBAC-by-default (#9720). Requires migration-chain design judgment, not a local fix — out of scope for the sweep.

  3. github-actions commented on Jun 11, 2026

    @github-actions
    Contributor

    PR #9988 (merged to Dev_new_gui) references this issue with a close keyword.

    fix(backend): repair Alembic chain + compose migration bootstrap — fresh-DB upgrade now reaches head (#9759)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  4. mrveiss commented on Jun 11, 2026

    @mrveiss
    OwnerAuthor

    Fixed by PR #9988 (merged to Dev_new_gui, squash afd58590d).

    • Chain repaired end-to-end: fresh Postgres 16 alembic upgrade head → 20260608_053 (68 tables); idempotent re-run; legacy create_all-secrets DB also upgrades clean
    • Root causes beyond the original report: 002 altered a create_all-only secrets table; 018 altered 5 more create_all-only tables; 022/027/030/031/032/036 re-emitted CREATE TYPE (generic sa.Enum ignores create_type=False); 047 duplicate index; env.py async/sync driver mismatch
    • Docker startup wiring: backend entrypoint runs alembic upgrade head (1 retry) for Postgres-backed user modes before uvicorn — AUTOBOT_USER_MODE=single_company is now a single-var flip
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions