Compare commits

...

1 Commits

Author SHA1 Message Date
Kit Langton
6b7d434c3c fix(migration): unblock workspace.time_used add on populated tables
The 20260507164347_add_workspace_time migration shipped as

    ALTER TABLE \`workspace\` ADD \`time_used\` integer NOT NULL;

bun:sqlite (and standard SQLite) refuse to add a NOT NULL column
without a DEFAULT to a non-empty table. Anyone upgrading from
v1.14.41 (Hono) to v1.14.42 with populated workspace rows hit
"Cannot add a NOT NULL column with default value NULL" at startup
and the app crashed before reaching the TUI.

Dev users hadn't noticed because they pulled the migration when
their workspace table was empty (or under a fresh fixture); the
ALTER then succeeded and was journaled. State C (empty table at
migration time = success), state A/B (populated table at migration
time = crash) — only state A/B users hit the bug, and only on
upgrade from v1.14.41.

Replace with a table-recreate pattern that is idempotent across
both states. The SELECT pulls only columns from the v1.14.41
schema, so it works whether time_used exists or not. The new
table defines time_used with DEFAULT 0; existing rows reset to 0,
which is acceptable because time_used is a usage counter the app
re-derives anyway and is brand new in v1.14.42.

Verified locally on bun:sqlite for both states.
2026-05-09 14:02:18 -04:00

View File

@@ -1 +1,27 @@
ALTER TABLE `workspace` ADD `time_used` integer NOT NULL;
-- Add workspace.time_used. The original migration was
-- ALTER TABLE `workspace` ADD `time_used` integer NOT NULL;
-- which fails on bun:sqlite for any user with existing workspace rows because
-- SQLite refuses to add a NOT NULL column without a default to a non-empty
-- table. Replaced with a table-recreate pattern that is safe regardless of
-- whether the column already exists (e.g. user successfully ran the original
-- migration on an empty workspace table) or doesn't (e.g. user upgrading from
-- v1.14.41 with populated workspace rows hit the original failure).
CREATE TABLE `__new_workspace` (
`id` text PRIMARY KEY NOT NULL,
`type` text NOT NULL,
`name` text DEFAULT '' NOT NULL,
`branch` text,
`directory` text,
`extra` text,
`project_id` text NOT NULL,
`time_used` integer DEFAULT 0 NOT NULL,
FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
INSERT INTO `__new_workspace` (`id`, `type`, `name`, `branch`, `directory`, `extra`, `project_id`)
SELECT `id`, `type`, `name`, `branch`, `directory`, `extra`, `project_id` FROM `workspace`;
--> statement-breakpoint
DROP TABLE `workspace`;
--> statement-breakpoint
ALTER TABLE `__new_workspace` RENAME TO `workspace`;