gastownhall/beads · error
db: CommentSQLRepository.InsertRecord: check issue existence
Error message
db: CommentSQLRepository.InsertRecord: check issue existence: %w
What it means
Before inserting, InsertRecord runs SELECT EXISTS(...) against the issue table (issues or issues_wisps, per CommentOpts.UseWispsTable) to verify the parent issue exists. This error wraps any failure of that probe query itself — connection loss, SQL syntax/permission errors, a missing table, or a cancelled context — not the case of the issue being absent (that is a separate error).
Source
Thrown at internal/storage/domain/db/comment.go:142
}
return r.InsertRecord(ctx, &types.Comment{IssueID: issueID, Author: author, Text: text, CreatedAt: stamp}, opts)
}
func (r *commentSQLRepositoryImpl) InsertRecord(ctx context.Context, comment *types.Comment, opts domain.CommentOpts) (*types.Comment, error) {
if comment == nil {
return nil, fmt.Errorf("db: CommentSQLRepository.InsertRecord: comment must not be nil")
}
copy := *comment
if copy.IssueID == "" {
return nil, fmt.Errorf("db: CommentSQLRepository.InsertRecord: issueID must not be empty")
}
issueTable := pickIssueTable(opts.UseWispsTable)
var exists bool
//nolint:gosec // G201: issueTable is one of two hardcoded constants
if err := r.runner.QueryRowContext(ctx,
fmt.Sprintf("SELECT EXISTS(SELECT 1 FROM %s WHERE id = ?)", issueTable), copy.IssueID).Scan(&exists); err != nil {
return nil, fmt.Errorf("db: CommentSQLRepository.InsertRecord: check issue existence: %w", err)
}
if !exists {
return nil, fmt.Errorf("db: CommentSQLRepository.InsertRecord: issue %s not found", copy.IssueID)
}
if copy.CreatedAt.IsZero() {
copy.CreatedAt = time.Now().UTC()
} else {
copy.CreatedAt = copy.CreatedAt.UTC()
}
createdAtText := issueops.FormatAuxTime(copy.CreatedAt)
commentTable := pickCommentTable(opts.UseWispsTable)
if copy.ID == "" {
id, _, err := issueops.InsertDerivedComment(ctx, r.runner, commentTable, copy.IssueID, copy.Author, copy.Text, createdAtText)
if err != nil {
return nil, fmt.Errorf("db: CommentSQLRepository.InsertRecord: %w", err)
}
copy.ID = idView on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause (%w) — it names the real SQL failure.
- Run schema migration/doctor so the chosen issue table (issues vs issues_wisps) exists.
- Verify opts.UseWispsTable matches the database generation you are actually connected to.
- Check DB connectivity and permissions, then retry; confirm the context isn't already cancelled.
Example fix
// before
repo.InsertRecord(ctx, c, domain.CommentOpts{UseWispsTable: true}) // old DB lacks issues_wisps
// after
opts := domain.CommentOpts{UseWispsTable: schemaSupportsWisps(db)}
repo.InsertRecord(ctx, c, opts) Defensive patterns
Strategy: try-catch
Validate before calling
// check connectivity and schema before calling
if err := runner.PingContext(ctx); err != nil {
return fmt.Errorf("database unavailable: %w", err)
} Type guard
null
Try / catch
if _, err := repo.InsertRecord(ctx, c, opts); err != nil {
if strings.Contains(err.Error(), "check issue existence") {
cause := errors.Unwrap(err)
// driver-level failure: inspect cause, verify schema (issues/issues_wisps)
// and connectivity, then retry with backoff
}
} Prevention
- Ping the database and verify schema before batch comment imports.
- Keep UseWispsTable consistent with the actual schema generation.
- Use contexts with sane timeouts so cancelled queries fail predictably.
- Wrap transient SQL failures with bounded retry/backoff at the call site.
When it happens
Trigger: The QueryRowContext(...).Scan(&exists) call returns a non-sql.ErrNoRows error: DB closed/misbehaving, the issue table (issues or issues_wisps) does not exist in this database, schema drift, permission denied on SELECT, or ctx cancelled mid-query.
Common situations: Pointing bd at a legacy or partially-migrated database where issues_wisps does not exist yet; a locked or crashed Dolt/SQLite file; network drop to a remote Dolt server; passing UseWispsTable: true against an old schema.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- db: GetMetadata %s: %w
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
- failed to query orphaned dependencies: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/00f58625a620655a.
Report an issue: GitHub.