{"record":{"id":"c9ed68059f482fb4","repo":"gastownhall/beads","slug":"delete-config-s-w","errorCode":null,"errorMessage":"delete config %s: %w","messagePattern":"delete config (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/bulk_ops.go","lineNumber":96,"sourceCode":"\tfor wispRows.Next() {\n\t\tvar id string\n\t\tif err := wispRows.Scan(&id); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"scan wisp issue id: %w\", err)\n\t\t}\n\t\tids = append(ids, id)\n\t}\n\tif err := wispRows.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"iterate wisp issues by label: %w\", err)\n\t}\n\n\treturn ids, nil\n}\n\n// DeleteConfigInTx removes a configuration value.\nfunc DeleteConfigInTx(ctx context.Context, tx *sql.Tx, key string) error {\n\t_, err := tx.ExecContext(ctx, \"DELETE FROM config WHERE `key` = ?\", key)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"delete config %s: %w\", key, err)\n\t}\n\treturn nil\n}\n\n// GetCommentsForIssuesInTx retrieves comments for multiple issues, partitioning\n// between comments and wisp_comments tables.\n//\n//nolint:gosec // G201: table is hardcoded\nfunc GetCommentsForIssuesInTx(ctx context.Context, tx *sql.Tx, issueIDs []string) (map[string][]*types.Comment, error) {\n\tif len(issueIDs) == 0 {\n\t\treturn make(map[string][]*types.Comment), nil\n\t}\n\n\tresult := make(map[string][]*types.Comment)\n\n\t// Partition IDs by wisp status in a single batched query, to avoid N\n\t// round-trips on remote backends (GH#3414).\n\twispIDs, permIDs, err := PartitionWispIDsInTx(ctx, tx, issueIDs)","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/bulk_ops.go#L78-L114","documentation":"DeleteConfigInTx wraps the ExecContext error from deleting a row in the config table with this message, including the key being deleted. It means the DELETE statement itself failed — not that the key was missing (a missing key deletes zero rows without error).","triggerScenarios":"tx.ExecContext(\"DELETE FROM config WHERE `key` = ?\") fails: connection loss, context cancellation, SQL syntax/schema errors, table locked, or read-only transaction.","commonSituations":"Dolt server unavailable mid-transaction; schema drift where the config table is missing; context deadline expiring during the delete; embedded database file locked by another process.","solutions":["Inspect the wrapped driver error; fix the underlying cause (connectivity, schema, locking) and retry the transaction.","Extend or fix the context deadline if the delete was cancelled by timeout.","Verify the config table exists and matches the expected schema (run bd doctor / migrations) if the error indicates a SQL/schema problem."],"exampleFix":"// before\nerr := issueops.DeleteConfigInTx(ctx, tx, \"my.key\")\n// after\nif err := issueops.DeleteConfigInTx(ctx, tx, \"my.key\"); err != nil {\n    if errors.Is(ctx.Err(), context.DeadlineExceeded) {\n        ctx, cancel = context.WithTimeout(context.Background(), 30*time.Second)\n        defer cancel()\n        err = retryTx(ctx, func(tx *sql.Tx) error { return issueops.DeleteConfigInTx(ctx, tx, \"my.key\") })\n    }\n}","handlingStrategy":"try-catch","validationCode":"func canDeleteConfig(ctx context.Context, tx *sql.Tx) error {\n    if ctx.Err() != nil { return ctx.Err() }\n    var n int\n    return tx.QueryRowContext(ctx, \"SELECT COUNT(*) FROM config\").Scan(&n)\n}","typeGuard":null,"tryCatchPattern":"if err := issueops.DeleteConfigInTx(ctx, tx, key); err != nil {\n    var base error\n    errors.As(err, &base) // inspect wrapped driver error\n    return fmt.Errorf(\"config delete aborted, retry whole tx: %w\", err)\n}","preventionTips":["Wrap deletes in a transaction you can retry whole on transient failures.","Check ctx.Err() before issuing writes with tight deadlines.","Verify config table schema exists before delete operations (migrations/doctor).","Distinguish 'no rows deleted' (success) from exec errors — don't pre-check existence."],"tags":["go","database","sql","config"],"backgroundTag":"sql-exec-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}