fix(kanban): hoist all additive-column indexes out of SCHEMA_SQL (#28461) - #28781
Merged
kshitijk4poor merged 2 commits intoMay 19, 2026
Merged
Conversation
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
Salvage of #28461 — fixes the Kanban DB legacy-migration crash reported in #28464 (and rediscovered in #28554, #28617, #28654, #28698) where
connect()runsSCHEMA_SQLbefore_migrate_add_optional_columns(), so a legacy board missing any additive indexed column aborts schema init withOperationalError: no such column: <col>before the migration can add it.The community filed six PRs for this bug (all on 2026-05-19). #28461 (itsreverence) was first and best-explained but only covered 2 of the 4 vulnerable indexes. #28754 (quocanh261997) extended coverage to 3 of the 4. This salvage combines the strengths of all the open PRs and closes the remaining gap.
What changed
Move every
CREATE INDEXthat depends on an additive column out ofSCHEMA_SQLand create them after_migrate_add_optional_columns()adds the columns. All four additive-column indexes are now hoisted:idx_tasks_session_idtasks.session_ididx_tasks_tenanttasks.tenantidx_tasks_idempotencytasks.idempotency_keyidx_events_runtask_events.run_idThree of these were ticking landmines for any user whose board predated the column.
idx_tasks_session_idwas the one that bit users today because it's the most recent (#28447 merged the day before the bug reports flooded in), but the same migration trap applied to all four.Beyond #28754's coverage:
idx_events_run: also hoisted out ofSCHEMA_SQLand made unconditional in the migration. A legacytask_eventstable predating feat(kanban): durable multi-profile collaboration board #17805 (norun_id) was still hitting the same SQLite trap that fix(kanban): migrate task session index after columns #28754 only addressed fortasks.idx_tasks_idempotency: removed the redundant inner-conditional create (line ~1085) that was nested insideif "idempotency_key" not in cols:. Since the unconditional create lower in the function already runsCREATE INDEX IF NOT EXISTS, the inner one was dead code on fresh DBs once we removed the SCHEMA_SQL line.task_eventsshape that exercises therun_idmigration path.tasks.<new_col>doesn't re-introduce the trap.test_max_runtime_uses_current_run_start_after_retrynowmonkeypatch-eskb._pid_aliveso it stops trippingtests/conftest.py's live-system guard onos.kill(<fake_pid>, 0). Pre-existing failure onorigin/main, unrelated to the index ordering bug; carried in via the cherry-pick rather than split out separately.Validation
Confirmed against
origin/main:Confirmed on this branch:
Test suite:
Full
tests/hermes_cli/suite — 4888 passed, 13 pre-existing failures unrelated to kanban (gateway service / model picker / plugins) that matchorigin/main1:1.Lint diff: zero new ruff/ty issues vs
origin/main(123 ty issues on changed files, identical on both base and head).Credit
Original bug report and PR by @itsreverence (#28464 + #28461 — first to file, best write-up of the underlying ordering trap).
Cherry-picked commit on this branch authored by @quocanh261997 from #28754 (broadest open coverage — included
tasks.tenantandtasks.idempotency_key).Other PRs absorbed and to be closed as duplicates: #28741 (@stormhierta), #28562 (@kungunier), #28620 (@vanhci), #28602 (@verybigdog, DRAFT). All of them correctly diagnosed the bug; this salvage combines the broadest coverage with the most thorough comments and tests.
Closes #28464.
Closes #28554.
Closes #28617.
Closes #28654.
Closes #28698.