{"record":{"id":"00f58625a620655a","repo":"gastownhall/beads","slug":"db-commentsqlrepository-insertrecord-check-issue","errorCode":null,"errorMessage":"db: CommentSQLRepository.InsertRecord: check issue existence: %w","messagePattern":"db: CommentSQLRepository\\.InsertRecord: check issue existence: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/comment.go","lineNumber":142,"sourceCode":"\t}\n\treturn r.InsertRecord(ctx, &types.Comment{IssueID: issueID, Author: author, Text: text, CreatedAt: stamp}, opts)\n}\n\nfunc (r *commentSQLRepositoryImpl) InsertRecord(ctx context.Context, comment *types.Comment, opts domain.CommentOpts) (*types.Comment, error) {\n\tif comment == nil {\n\t\treturn nil, fmt.Errorf(\"db: CommentSQLRepository.InsertRecord: comment must not be nil\")\n\t}\n\tcopy := *comment\n\tif copy.IssueID == \"\" {\n\t\treturn nil, fmt.Errorf(\"db: CommentSQLRepository.InsertRecord: issueID must not be empty\")\n\t}\n\n\tissueTable := pickIssueTable(opts.UseWispsTable)\n\tvar exists bool\n\t//nolint:gosec // G201: issueTable is one of two hardcoded constants\n\tif err := r.runner.QueryRowContext(ctx,\n\t\tfmt.Sprintf(\"SELECT EXISTS(SELECT 1 FROM %s WHERE id = ?)\", issueTable), copy.IssueID).Scan(&exists); err != nil {\n\t\treturn nil, fmt.Errorf(\"db: CommentSQLRepository.InsertRecord: check issue existence: %w\", err)\n\t}\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"db: CommentSQLRepository.InsertRecord: issue %s not found\", copy.IssueID)\n\t}\n\n\tif copy.CreatedAt.IsZero() {\n\t\tcopy.CreatedAt = time.Now().UTC()\n\t} else {\n\t\tcopy.CreatedAt = copy.CreatedAt.UTC()\n\t}\n\tcreatedAtText := issueops.FormatAuxTime(copy.CreatedAt)\n\tcommentTable := pickCommentTable(opts.UseWispsTable)\n\tif copy.ID == \"\" {\n\t\tid, _, err := issueops.InsertDerivedComment(ctx, r.runner, commentTable, copy.IssueID, copy.Author, copy.Text, createdAtText)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"db: CommentSQLRepository.InsertRecord: %w\", err)\n\t\t}\n\t\tcopy.ID = id","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/comment.go#L124-L160","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nrepo.InsertRecord(ctx, c, domain.CommentOpts{UseWispsTable: true}) // old DB lacks issues_wisps\n// after\nopts := domain.CommentOpts{UseWispsTable: schemaSupportsWisps(db)}\nrepo.InsertRecord(ctx, c, opts)","handlingStrategy":"try-catch","validationCode":"// check connectivity and schema before calling\nif err := runner.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"database unavailable: %w\", err)\n}","typeGuard":"null","tryCatchPattern":"if _, err := repo.InsertRecord(ctx, c, opts); err != nil {\n    if strings.Contains(err.Error(), \"check issue existence\") {\n        cause := errors.Unwrap(err)\n        // driver-level failure: inspect cause, verify schema (issues/issues_wisps)\n        // and connectivity, then retry with backoff\n    }\n}","preventionTips":["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."],"tags":["go","sql","database","query-failure"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}