gastownhall/beads · error
db: CommentSQLRepository.InsertRecord: issue %s not found
Error message
db: CommentSQLRepository.InsertRecord: issue %s not found
What it means
The existence probe returned exists=false: the parent issue ID is valid non-empty text but no row with that id exists in the selected issue table (issues or issues_wisps). The repository refuses to create a comment for a nonexistent issue, keeping referential integrity.
Source
Thrown at internal/storage/domain/db/comment.go:145
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 = id
} else {
//nolint:gosec // G201: commentTable is one of two hardcoded constants
if _, err := r.runner.ExecContext(ctx, fmt.Sprintf(`View on GitHub (pinned to 71377f2769)
Solutions
- Verify the issue ID exists (bd show <id> or SELECT) in the same database and table selection.
- Correct the IssueID (typo/prefix) or create the issue first.
- Make opts.UseWispsTable consistent with how the issue was created (wisp vs regular issue).
- Skip/requeue comments whose parent issue was deleted instead of failing the whole import.
Example fix
// before
repo.InsertRecord(ctx, &types.Comment{IssueID: "bd-999", Text: "x"}, opts) // bd-999 absent
// after
if issue, err := issueRepo.Get(ctx, "bd-999"); err == nil {
repo.InsertRecord(ctx, &types.Comment{IssueID: issue.ID, Text: "x"}, opts)
} Defensive patterns
Strategy: validation
Validate before calling
// ensure the parent issue exists before inserting the comment
var exists bool
_ = runner.QueryRowContext(ctx,
"SELECT EXISTS(SELECT 1 FROM issues WHERE id = ?)", issueID).Scan(&exists)
if !exists {
return fmt.Errorf("refusing to comment on unknown issue %s", issueID)
} Type guard
func issueExists(ctx context.Context, r domain.IssueSQLRepository, id string) bool {
_, err := r.Get(ctx, id)
return err == nil
} Try / catch
if _, err := repo.InsertRecord(ctx, c, opts); err != nil {
if strings.Contains(err.Error(), "not found") && strings.Contains(err.Error(), c.IssueID) {
// create or look up the correct issue first; skip orphan comments in imports
}
} Prevention
- Fetch the issue object and use its ID rather than re-typing IDs by hand.
- During imports, import issues before comments and validate referential integrity.
- Never mix IDs across databases; verify with bd show before writing.
- Keep UseWispsTable aligned with where the issue was created.
When it happens
Trigger: InsertRecord(ctx, &types.Comment{IssueID: "bd-123", ...}, opts) where bd-123 is not in the issue table — wrong prefix, typo'd ID, ID from a different database, or UseWispsTable set inconsistently with where the issue actually lives (issue created in wisps table but comment inserted with the wrong table selection, or vice versa).
Common situations: Copy-pasting IDs between repos/databases, importing comments before importing the issues, stale IDs after a DB reset, or a mismatch between the table chosen via opts.UseWispsTable and where the issue was created.
Related errors
- no store is open for this workspace
- molecule %s not found: %w
- issue %s not found
- epic '%s' not found
- issue '%s' not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/cd96cd0c86e7b281.
Report an issue: GitHub.