fix(controller): skip DB migration when DB schema is ahead of binary#1963
fix(controller): skip DB migration when DB schema is ahead of binary#1963onematchfox wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR makes the migration runner tolerant of running an older binary against a database schema migrated by a newer binary, avoiding crash-loops by skipping migration application when the DB version is ahead of the binary’s embedded migrations.
Changes:
- Add a “compatibility mode” early-return in
applyDirwhen DB schema version exceeds the binary’s max embedded migration version. - Introduce
maxEmbeddedVersionto compute the highest embedded migration version from the filesystem. - Add a regression test ensuring
applyDirsucceeds (and does not modify schema version) when the DB version is ahead.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| go/core/pkg/migrations/runner.go | Adds compatibility-mode logic and a helper to scan embedded migrations for the max version. |
| go/core/pkg/migrations/runner_test.go | Adds a test proving older binaries don’t error or roll back when DB schema is ahead. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
40aad83 to
9382b86
Compare
9382b86 to
f39b229
Compare
When an older binary starts against a database that a newer binary has already migrated, calling mg.Up() fails because golang-migrate tries to read the down file for the current DB version, which does not exist in the older binary's embedded FS. This caused a crash loop (issue kagent-dev#1881). Instead, detect when the database version exceeds the binary's highest known migration and return early. This relies on the expand-then-contract policy documented in database-migrations.md, which guarantees each release's code is compatible with the schema applied by the previous release. Adds TestApplyDir_SucceedsWhenDBVersionAhead to cover this path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com>
f39b229 to
aa49e3e
Compare
iplay88keys
left a comment
There was a problem hiding this comment.
This might be changed when we update the db migration/rollback logic, but this is a good incremental improvement in the meantime.
Thinking more about this so we don't introduce a footgun here.
|
Sorry for un-approving this PR. I want to make sure the implications of this change are well thought through. Let's start with aligning on a few things:
The current db migrations are set up such that the application fails to start if there are more migrations applied to the db than the binary knows about. This is by design to prevent data corruption. There is no way for the binary to know what migrations are in n+1 vs n+2 without going back and editing the old artifacts or making this incompatible with airgapped environments. This PR removes the aforementioned check (comparing known migrations vs what's migrated), effectively introducing a requirement that Kagent stays compatible with future database schema shape changes and queries. It also leaves a subtle footgun as the information regarding the "compatibility mode" is only surfaced in a log line. Even with this change, there is still a manual database rollback requirement in order to not be in an inconsistent state. So I'm not sure that it's worth taking on these additional support burdens in that case. |
When an older binary starts against a database that a newer binary has already migrated, calling
mg.Up()fails because golang-migrate tries to read the down file for the current DB version, which does not exist in the older binary's embedded FS. This results in the controller crash looping (issue #1881).Instead, detect when the database version exceeds the binary's highest known migration and return early. This relies on the expand-then-contract policy documented in database-migrations.md, which guarantees each release's code is compatible with the schema applied by the previous release.
Adds TestApplyDir_SucceedsWhenDBVersionAhead to cover this path.