Skip to content

[BLOCKER] Daemon panics on startup: duplicate goose migration version 25 (worker_idle_outbox + session_cleanup_facts)Β #3037

Description

@i-trytoohard

πŸ”΄ BLOCKER β€” Nightly channel completely broken

Reported by: @prateek (Discord #bug-triage)
Impact: Daemon cannot start β€” every macOS/Windows/Linux user on the latest nightly is dead in the water.

Error

panic: goose: duplicate version 25 detected:
    migrations/0025_worker_idle_outbox.sql
    migrations/0025_session_cleanup_facts.sql

goroutine 1 [running]:
github.com/pressly/goose/v3.Migrations.Less(...)
github.com/pressly/goose/v3.sortAndConnectMigrations(...)
github.com/pressly/goose/v3.collectMigrationsFS(...)
github.com/pressly/goose/v3.CollectMigrations(...)
github.com/pressly/goose/v3.UpToContext(...)
github.com/pressly/goose/v3.Up(...)
github.com/aoagents/agent-orchestrator/backend/internal/storage/sqlite.migrate()
    backend/internal/storage/sqlite/db.go:133
github.com/aoagents/agent-orchestrator/backend/internal/storage/sqlite.Open(...)
    backend/internal/storage/sqlite/db.go:69

The daemon exits with code 2 before any migration runs. The app shows: "AO daemon failed to start β€” Daemon exited with code 2".

Root cause

Two migration files share version number 0025:

File PR Merged
0025_worker_idle_outbox.sql #2836 July 22, 09:24 IST
0025_session_cleanup_facts.sql #2853 July 23, 18:17 IST

PR #2853's commit message even says "migration 0024: session_cleanup_facts" β€” the author intended version 0024, but 0024_session_rename_cdc.sql was already taken, and the file landed at 0025_ which collided with 0025_worker_idle_outbox.sql (merged the day before).

This is still broken on main right now (HEAD 9d841eb2). Any nightly built after July 23 18:17 IST is affected β€” including today's v0.10.4-nightly.202607231414 and .202607231443.

Fix

Rename 0025_session_cleanup_facts.sql β†’ 0030_session_cleanup_facts.sql (next available version after the current max 0029).

This is safe because:

  • The panic happens in CollectMigrations before Up() runs, so no broken migration was ever partially applied to any user's DB.
  • Users on the previous working nightly already have version 25 (worker_idle_outbox) applied β€” after the rename, goose will see 0025 done and apply 0026–0030 cleanly.
  • Fresh installs on the broken nightly panicked every launch, so their DB is untouched.
- backend/internal/storage/sqlite/migrations/0025_session_cleanup_facts.sql
+ backend/internal/storage/sqlite/migrations/0030_session_cleanup_facts.sql

Prevention

Goose doesn't validate unique version numbers at authoring time β€” only at runtime (where it panics). Consider:

  • A CI test that runs goose collect (or just loads all migrations) to catch duplicate versions before they ship.
  • A pre-commit or lint check that fails if two files match the same ^\d{4}_ prefix.

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions