Skip to content

fix(kanban): run column migrations before SCHEMA_SQL on existing DBs - #29203

Closed
maskiey wants to merge 1 commit into
NousResearch:mainfrom
maskiey:fix/kanban-schema-migration-order
Closed

fix(kanban): run column migrations before SCHEMA_SQL on existing DBs#29203
maskiey wants to merge 1 commit into
NousResearch:mainfrom
maskiey:fix/kanban-schema-migration-order

Conversation

@maskiey

@maskiey maskiey commented May 20, 2026

Copy link
Copy Markdown

Summary

Fixes a bug where gateway upgrades cause 100% CPU and broken kanban dispatcher.

Root Cause

conn.executescript(SCHEMA_SQL) references columns (e.g. session_id) via index creation that don't exist in pre-existing databases. The old code ran SCHEMA_SQL first, which would fail when trying to CREATE INDEX on a missing column, preventing _migrate_add_optional_columns() from ever running.

Fix

Check if the tasks table already exists before running SCHEMA_SQL. If it does, run additive column migrations FIRST so all columns exist before any index creation attempts. The post-SCHEMA_SQL migration call is kept (idempotent) to handle fresh databases.

Reproduction

  1. Run an older version of Hermes Agent that creates kanban.db without session_id column
  2. Upgrade to a version that includes session_id in SCHEMA_SQL
  3. Gateway dispatcher enters tight retry loop at 100% CPU with:
    sqlite3.OperationalError: no such column: session_id

Test Plan

  • Fresh install: kanban.db created correctly with all columns and indexes
  • Upgrade from pre-session_id DB: migration runs first, SCHEMA_SQL succeeds
  • Gateway dispatcher starts without errors

When a gateway is upgraded, the kanban SCHEMA_SQL may reference
columns (e.g. session_id) that don't exist in pre-existing databases.
The old code ran conn.executescript(SCHEMA_SQL) first, which would
fail when trying to CREATE INDEX on a missing column, preventing
_migrate_add_optional_columns() from ever running.

Fix: check if the tasks table already exists and, if so, run additive
column migrations BEFORE SCHEMA_SQL. This ensures all columns exist
before any index creation attempts. The post-SCHEMA_SQL migration
call is kept (idempotent) to handle fresh databases.

Repro: gateway running with a pre-session_id kanban.db would enter
a tight retry loop at 100% CPU because every dispatcher tick failed
with 'sqlite3.OperationalError: no such column: session_id'.
@maskiey
maskiey force-pushed the fix/kanban-schema-migration-order branch from 597cb2f to 8229b35 Compare May 20, 2026 09:07
@alt-glitch alt-glitch added type/bug Something isn't working duplicate This issue or pull request already exists comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have labels May 20, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #28461 / #28781 (merged). The kanban migration ordering bug (SCHEMA_SQL indexes referencing columns not yet added by _migrate_add_optional_columns()) was already fixed comprehensively by #28781 which hoists all 4 additive-column indexes. See also #28464 (canonical issue), #28844 (open dup).

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for filing this — the migration-ordering bug is already fixed on current main by the merged #28781.

Automated hermes-sweeper review evidence:

  • fix(kanban): hoist all additive-column indexes out of SCHEMA_SQL (#28461) #28781 merged as 7552e0f3c0723f56c7ee8d5e2fe6c53c7a1f6ac3, and its PR body covers this exact failure mode: SCHEMA_SQL ran before _migrate_add_optional_columns(), so legacy Kanban DBs missing additive columns could fail on index creation.
  • Current hermes_cli/kanban_db.py keeps additive-column indexes out of SCHEMA_SQL; idx_tasks_session_id, idx_tasks_tenant, idx_tasks_idempotency, and idx_events_run are created after the additive column migrations run in _migrate_add_optional_columns().
  • The regression test at tests/hermes_cli/test_kanban_db.py:112 creates a legacy DB missing session_id and the other additive indexed columns, opens it through kb.connect(), and asserts the columns plus indexes are present after migration.

Closing as implemented on main.

@teknium1 teknium1 closed this Jun 20, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants