fix(kanban): make column migrations idempotent under concurrent access - #21529
Closed
luyao618 wants to merge 1 commit into
Closed
fix(kanban): make column migrations idempotent under concurrent access#21529luyao618 wants to merge 1 commit into
luyao618 wants to merge 1 commit into
Conversation
The `_migrate_add_optional_columns()` function reads the column list once via `PRAGMA table_info` and guards each `ALTER TABLE ADD COLUMN` with an `if col not in cols` check. When two gateway processes run the migration concurrently (e.g. during a restart), both snapshots see the old schema and both attempt the same ALTER TABLE — the second one crashes with `sqlite3.OperationalError: duplicate column name`. Introduce a `_safe_add_column()` helper that wraps each ALTER TABLE in a try/except for `sqlite3.OperationalError`, making every individual statement idempotent regardless of snapshot freshness. SQLite lacks `ADD COLUMN IF NOT EXISTS`, so this is the standard approach. All 14 ALTER TABLE ADD COLUMN statements in the migration (across both the `tasks` and `task_events` tables) now use the helper. Closes NousResearch#21503
This was referenced May 7, 2026
Contributor
|
Closing as superseded. PR #22627 (already merged) addressed the same duplicate-column race with |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make
_migrate_add_optional_columns()safe under concurrent execution by wrapping eachALTER TABLE ADD COLUMNin a try/except helper (_safe_add_column()).Problem
When two gateway processes run migrations concurrently (e.g. during a restart), both read the same
PRAGMA table_infosnapshot before either modifies the schema. Both pass theif col not in colsguard and attempt the sameALTER TABLE ADD COLUMN, causing:This crashes the kanban dispatcher on every tick, preventing it from starting.
All 14
ALTER TABLE ADD COLUMNstatements in the migration were vulnerable.Fix
Introduce
_safe_add_column(conn, table, column, typedef)that catchessqlite3.OperationalErroron duplicate column — the standard SQLite idiom sinceADD COLUMN IF NOT EXISTSis not supported. All 14 ALTER TABLE statements now use this helper.The helper returns
boolso callers that need to conditionally run follow-up logic (e.g. data copy from legacy columns) can check whether the column was actually added.Testing
test_kanban_db.py: 60 passed,test_kanban_core_functionality.py: 148 passed)Closes #21503