{"record":{"id":"c225b39dcd95de56","repo":"gastownhall/beads","slug":"db-setconfig-s-w","errorCode":null,"errorMessage":"db: SetConfig %s: %w","messagePattern":"db: SetConfig (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/config.go","lineNumber":83,"sourceCode":"\nfunc (r *configSQLRepositoryImpl) GetConfig(ctx context.Context, key string) (string, error) {\n\tvar value string\n\terr := r.runner.QueryRowContext(ctx, \"SELECT value FROM config WHERE `key` = ?\", key).Scan(&value)\n\tif errors.Is(err, sql.ErrNoRows) {\n\t\treturn \"\", nil\n\t}\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"db: GetConfig %s: %w\", key, err)\n\t}\n\treturn value, nil\n}\n\nfunc (r *configSQLRepositoryImpl) SetConfig(ctx context.Context, key, value string) error {\n\tif key == \"issue_prefix\" {\n\t\tvalue = strings.TrimSuffix(value, \"-\")\n\t}\n\tif _, err := r.runner.ExecContext(ctx, \"REPLACE INTO config (`key`, value) VALUES (?, ?)\", key, value); err != nil {\n\t\treturn fmt.Errorf(\"db: SetConfig %s: %w\", key, err)\n\t}\n\t// Re-sync the normalized lookup table a value backs, mirroring\n\t// DoltStore.SetConfig. Reads are TABLE-FIRST — GetCustomTypes above\n\t// consults custom_types and falls back to the string only when the table is\n\t// empty, and GetCustomStatuses reads custom_statuses outright — so a write\n\t// that updated only the string left the table holding the previous set,\n\t// forever: `bd config set types.custom` on a proxied deployment reported\n\t// success and `bd create -t <the new type>` kept answering \"invalid issue\n\t// type\", with doctor re-verifying against the string and reporting all-OK.\n\t//\n\t// The caller supplies a transactional runner, so the row and its projection\n\t// commit together or neither does.\n\tif _, err := issueops.SyncConfigTables(ctx, r.runner, key, value); err != nil {\n\t\treturn fmt.Errorf(\"db: SetConfig %s: %w\", key, err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/config.go#L65-L101","documentation":"This error wraps failure of the REPLACE INTO config statement inside SetConfig. SetConfig writes a config key/value and then re-syncs the normalized lookup tables (custom_types, custom_statuses); this wrapper specifically covers the initial row write failing. The SQL repo intentionally mirrors DoltStore.SetConfig semantics so both backends behave identically.","triggerScenarios":"Calling SetConfig(ctx, key, value) when the REPLACE INTO config (`key`, value) ExecContext fails: missing config table, database lock, connection loss, or driver constraint/IO error.","commonSituations":"Running `bd config set` or prefix setup against a stale-schema database; concurrent bd processes contending for the DB lock; disk full while writing; an old binary opening a migrated database.","solutions":["Run schema setup/migration (e.g. `bd doctor`) to ensure the config table exists","Retry after confirming no other process holds the database lock","Check disk space and write permissions on the database file","Inspect the wrapped cause and address the specific driver error","Restore from backup if the database is corrupted"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := ensureSchemaMigrated(ctx); err != nil {\n\treturn fmt.Errorf(\"config table unavailable: %w\", err)\n}\nif locked := dbLockedByOtherProcess(); locked {\n\treturn fmt.Errorf(\"database locked by another bd process\")\n}","typeGuard":null,"tryCatchPattern":"err := retry.Do(3, retry.Backoff(time.Second), func() error {\n\treturn repo.SetConfig(ctx, key, value)\n})\nif err != nil {\n\treturn fmt.Errorf(\"could not set config %q after retries: %w\", key, err)\n}","preventionTips":["Retry transient lock/IO failures with backoff before surfacing","Migrate schema after bd upgrades so the config table exists","Verify write permissions and disk space before bulk config changes","Use `bd config set` rather than editing the database directly"],"tags":["database","storage","dolt","write-failed","config"],"backgroundTag":"sql-write-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}