{"record":{"id":"144350265e561e55","repo":"gastownhall/beads","slug":"seeding-dolt-ignore-pattern-q-w","errorCode":null,"errorMessage":"seeding dolt_ignore pattern %q: %w","messagePattern":"seeding dolt_ignore pattern %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/schema.go","lineNumber":439,"sourceCode":"// read costs one round trip and removes the need for that grant.\n//\n// The write path is unchanged where a write is genuinely owed: INSERT IGNORE\n// leaves existing rows untouched, so an explicit operator override (pattern\n// present with ignored=false) is respected even in the race where the probe\n// missed it. On an under-seeded database the new rows land in the working set\n// and take effect immediately; who commits them depends on the pass: when\n// migration work is needed, MigrateUp exempts dolt_ignore from the\n// pre-existing-dirty guards as pass-owned state (same treatment as the\n// aux-rekey tables) and stageSchemaTables commits it with the pass; on the\n// no-work short-circuit, MigrateUp commits the seed itself in a scoped,\n// labeled commit (keyed off the changed return value) so the heal converges\n// in one pass instead of riding along inside an unrelated later commit.\nfunc seedDoltIgnorePatterns(ctx context.Context, db DBConn) (bool, error) {\n\tchanged := false\n\tfor _, pattern := range missingDoltIgnorePatterns(ctx, db, doltIgnoreSeedCandidates(ctx, db)) {\n\t\tres, err := db.ExecContext(ctx, \"INSERT IGNORE INTO dolt_ignore VALUES (?, true)\", pattern)\n\t\tif err != nil {\n\t\t\treturn changed, fmt.Errorf(\"seeding dolt_ignore pattern %q: %w\", pattern, err)\n\t\t}\n\t\t// A RowsAffected error degrades to changed=false for that row: the\n\t\t// seed then stays an uncommitted working-set diff swept up by the\n\t\t// next commit, exactly the pre-scoped-commit behavior.\n\t\tif n, raErr := res.RowsAffected(); raErr == nil && n > 0 {\n\t\t\tchanged = true\n\t\t}\n\t}\n\treturn changed, nil\n}\n\n// commitSeededDoltIgnore stages and commits freshly seeded dolt_ignore rows\n// in a scoped, labeled commit. Both MigrateUp paths use it: on the no-work\n// short-circuit nothing downstream would ever commit the seed, and on the\n// migration path the seed must be committed before the first step so an\n// interrupted pass leaves a clean working set (#4566 self-heal contract).\nfunc commitSeededDoltIgnore(ctx context.Context, db DBConn) error {\n\tif err := DrainCall(ctx, db, \"CALL DOLT_ADD('dolt_ignore')\"); err != nil {","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/schema.go#L421-L457","documentation":"This error wraps a failed INSERT of a missing pattern into the `dolt_ignore` table during migration seeding. seedDoltIgnorePatterns runs as part of MigrateUp to ensure known junk artifacts (e.g. backup files) are ignored, and this error means one of those INSERT IGNORE statements failed at the SQL level.","triggerScenarios":"MigrateUp calling seedDoltIgnorePatterns on a database where `INSERT IGNORE INTO dolt_ignore VALUES (?, true)` errors — missing dolt_ignore table in an unexpected state, write to a read-only store, or a Dolt transaction/working-set conflict.","commonSituations":"Running `bd migrate` (or any command that triggers MigrateUp) against a read-only database; dolt_ignore exists but with an incompatible schema; Dolt server rejecting writes mid-migration.","solutions":["Check the wrapped cause — read-only store is the most common cause; open the workspace read-write instead","Verify the dolt_ignore table schema matches `dolt_ignore VALUES(pattern, ignored)`","Confirm the Dolt working set is clean (`dolt status`) before migrating","Retry MigrateUp; seeding is idempotent (INSERT IGNORE with presence pre-check)"],"exampleFix":"// before: read-only open causes seed insert to fail\ndb := openStoreReadOnly(path)\nschema.MigrateUp(ctx, db)\n// after: migrate via a writable connection\ndb := openStoreReadWrite(path)\nschema.MigrateUp(ctx, db)","handlingStrategy":"validation","validationCode":"// check dolt_ignore is present and writable before migrating\nif _, err := db.ExecContext(ctx, \"SELECT * FROM dolt_ignore LIMIT 1\"); err != nil {\n\treturn fmt.Errorf(\"dolt_ignore unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := schema.MigrateUp(ctx, db); err != nil {\n\tvar derr *fs.PathError\n\tif errors.As(err, &derr) || strings.Contains(err.Error(), \"read-only\") {\n\t\t// reopen writable and retry\n\t}\n}","preventionTips":["Always run migrations on a read-write connection","Keep the Dolt working set clean (`dolt status`) before migrating","Verify dolt_ignore schema matches the expected two-column shape"],"tags":["dolt","migration","dolt-ignore","seed"],"backgroundTag":"dolt-ignore-seed-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}