{"record":{"id":"b35ee08141df5c8a","repo":"gastownhall/beads","slug":"inserting-type-q-w","errorCode":null,"errorMessage":"inserting type %q: %w","messagePattern":"inserting type %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/schema/backfill.go","lineNumber":112,"sourceCode":"\n\tvar value string\n\terr := db.QueryRowContext(ctx, \"SELECT `value` FROM config WHERE `key` = 'types.custom'\").Scan(&value)\n\tif err == sql.ErrNoRows {\n\t\treturn false, nil\n\t}\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tif value == \"\" {\n\t\treturn false, nil\n\t}\n\n\twrote := false\n\t// ParseTypesConfigValue already trims elements and drops empties.\n\tfor _, name := range issueops.ParseTypesConfigValue(value) {\n\t\tres, err := db.ExecContext(ctx, \"INSERT IGNORE INTO custom_types (name) VALUES (?)\", name)\n\t\tif err != nil {\n\t\t\treturn wrote, fmt.Errorf(\"inserting type %q: %w\", name, err)\n\t\t}\n\t\tif n, err := res.RowsAffected(); err == nil && n > 0 {\n\t\t\twrote = true\n\t\t}\n\t}\n\treturn wrote, nil\n}\n\nfunc backfillCustomStatuses(ctx context.Context, db DBConn) (bool, error) {\n\tvar count int\n\tif err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM custom_statuses\").Scan(&count); err != nil {\n\t\treturn false, err\n\t}\n\tif count > 0 {\n\t\treturn false, nil\n\t}\n\n\tvar value string","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/schema/backfill.go#L94-L130","documentation":"This error wraps a failed INSERT IGNORE INTO custom_types (name) VALUES (?) while backfilling configured custom issue types during migration. INSERT IGNORE normally swallows duplicate rows, so a surfaced error is a real SQL failure — table missing, connection dropped, privilege denied, or another constraint.","triggerScenarios":"backfillCustomTypes iterates ParseTypesConfigValue(config['types.custom']) and one INSERT IGNORE returns a driver error: custom_types table doesn't exist, INSERT privilege missing, connection killed, or context cancelled mid-loop.","commonSituations":"Migrating a database where migrations creating custom_types were skipped; running under a limited DB role; server restart mid-backfill; corrupted config table producing odd values (parsing itself never errors — ParseTypesConfigValue trims/drops empties).","solutions":["Ensure all numbered migrations run before backfill so custom_types exists, then re-run MigrateUp.","Fix DB grants: the user needs INSERT on custom_types.","Restore Dolt connectivity and retry the migration; the count-gated backfill is safe to repeat.","Validate the 'types.custom' config value and config table integrity if failures persist."],"exampleFix":"// before: any single bad insert aborts the backfill\nres, err := db.ExecContext(ctx, \"INSERT IGNORE INTO custom_types (name) VALUES (?)\", name)\nif err != nil {\n\treturn wrote, fmt.Errorf(\"inserting type %q: %w\", name, err)\n}\n// after: ensure the table exists before inserting (only if migrations can't be reordered)\ndb.ExecContext(ctx, \"CREATE TABLE IF NOT EXISTS custom_types (name VARCHAR(255) PRIMARY KEY)\")\nres, err := db.ExecContext(ctx, \"INSERT IGNORE INTO custom_types (name) VALUES (?)\", name)","handlingStrategy":"retry","validationCode":"// Ensure custom_types exists and config is readable before backfill triggers\nvar n int\nif err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'custom_types'`).Scan(&n); err != nil || n == 0 {\n\treturn fmt.Errorf(\"custom_types missing; run migrations\")\n}\nvar v sql.NullString\nif err := db.QueryRowContext(ctx, \"SELECT `value` FROM config WHERE `key` = 'types.custom'\").Scan(&v); err != nil && err != sql.ErrNoRows {\n\treturn fmt.Errorf(\"config unreadable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := migrateUp(ctx)\nif err != nil && strings.Contains(err.Error(), \"inserting type \") {\n\tif isTransient(err) {\n\t\terr = migrateUp(ctx) // count-gated backfill resumes safely\n\t}\n}","preventionTips":["Run the full numbered-migration chain so custom_types exists before seeding","Grant INSERT on custom_types to the migration user","Keep the connection alive during migration (avoid aggressive idle timeouts)","Back up config table contents before schema upgrades"],"tags":["database","backfill","sql"],"backgroundTag":"schema-backfill-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}