{"record":{"id":"b7d3479609bfa347","repo":"gastownhall/beads","slug":"adding-wisp-dependencies-s-for-migration-0053-w","errorCode":null,"errorMessage":"adding wisp_dependencies.%s for migration 0053: %w","messagePattern":"adding wisp_dependencies\\.(.+?) for migration 0053: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/migration_repairs.go","lineNumber":632,"sourceCode":"// after that the source data needed to finish an interrupted backfill is\n// gone for good.\nfunc ensureWispDependenciesSplitTargets(ctx context.Context, db DBConn) error {\n\ttable, err := schemaTableExists(ctx, db, \"wisp_dependencies\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"checking wisp_dependencies table: %w\", err)\n\t}\n\tif !table {\n\t\treturn nil\n\t}\n\n\tfor _, col := range wispDependenciesSplitTargetColumns() {\n\t\tpresent, err := schemaColumnExists(ctx, db, \"wisp_dependencies\", col.name)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"checking wisp_dependencies.%s: %w\", col.name, err)\n\t\t}\n\t\tif !present {\n\t\t\tif _, err := db.ExecContext(ctx, \"ALTER TABLE wisp_dependencies ADD COLUMN \"+col.name+\" \"+col.definition); err != nil {\n\t\t\t\treturn fmt.Errorf(\"adding wisp_dependencies.%s for migration 0053: %w\", col.name, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tlegacyTarget, err := schemaColumnExists(ctx, db, \"wisp_dependencies\", \"depends_on_id\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"checking wisp_dependencies.depends_on_id: %w\", err)\n\t}\n\tif !legacyTarget {\n\t\t// Nothing left to backfill from: either a prior pass already\n\t\t// finished (depends_on_id has since been dropped) or this database\n\t\t// never had the legacy column to begin with.\n\t\treturn nil\n\t}\n\n\tfor _, repair := range wispDependenciesSplitTargetBackfillSQL() {\n\t\tif _, err := db.ExecContext(ctx, repair); err != nil {\n\t\t\treturn fmt.Errorf(\"backfilling wisp_dependencies split targets for migration 0053: %w\", err)","sourceCodeStart":614,"sourceCodeEnd":650,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/migration_repairs.go#L614-L650","documentation":"Wraps a failed ALTER TABLE wisp_dependencies ADD COLUMN when ensureWispDependenciesSplitTargets adds a missing split-target column (depends_on_issue_id/depends_on_wisp_id/depends_on_external) required by migration 0053. This is an actual DDL failure, so the schema may be partially repaired (some columns added, then one fails). The function is safe to re-run: present columns are skipped.","triggerScenarios":"db.ExecContext(\"ALTER TABLE wisp_dependencies ADD COLUMN <name> <definition>\") fails — duplicate column name raced in by a concurrent process, table locked by another writer, Dolt refusing DDL in the current session, or disk/resource errors.","commonSituations":"Two `bd` processes running migration repair concurrently on the same database; database opened read-only; Dolt version that rejects ALTER on a table with pending foreign keys; out-of-disk during DDL.","solutions":["Read the wrapped driver error: if 'duplicate column', a concurrent repair already added it — simply re-run and it will skip present columns.","Ensure only one process performs migrations at a time (use a lock or run `bd migrate` in a single session).","Confirm the database is writable (not opened read-only) and the user has ALTER privilege.","Re-run the repair; each step is idempotent and safe to repeat."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check column and skip ALTER if another process already added it\npresent, _ := schemaColumnExists(ctx, db, \"wisp_dependencies\", colName)\nif present { /* skip ALTER */ }","typeGuard":"func isDuplicateColumnErr(err error) bool {\n    return strings.Contains(err.Error(), \"Duplicate column name\")\n}","tryCatchPattern":"err := ensureWispDependenciesSplitTargets(ctx, db)\nif err != nil && isDuplicateColumnErr(err) {\n    // concurrent repair won the race; safe to proceed\n} else if err != nil {\n    return err\n}","preventionTips":["Serialize migrations with a lock (single migrator process)","Open the database read-write, never read-only, for repairs","Grant the DB user ALTER privilege","Ensure sufficient disk space before DDL"],"tags":["database","migration","ddl","alter-table"],"backgroundTag":"alter-table-add-column-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}