{"record":{"id":"5347307239be62a7","repo":"gastownhall/beads","slug":"db-labelsqlrepository-insert-s-s-issue-does-no","errorCode":null,"errorMessage":"db: LabelSQLRepository.Insert %s/%s: issue does not exist","messagePattern":"db: LabelSQLRepository\\.Insert (.+?)/(.+?): issue does not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/label.go","lineNumber":73,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: %w\", issueID, label, err)\n\t}\n\trows, err := result.RowsAffected()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: rows affected: %w\", issueID, label, err)\n\t}\n\tif rows == 0 {\n\t\tissueTable := \"issues\"\n\t\tif opts.UseWispsTable {\n\t\t\tissueTable = \"wisps\"\n\t\t}\n\t\tvar count int\n\t\t//nolint:gosec // G201: issueTable is one of two hardcoded constants.\n\t\tif err := r.runner.QueryRowContext(ctx, fmt.Sprintf(\"SELECT COUNT(*) FROM %s WHERE id = ?\", issueTable), issueID).Scan(&count); err != nil {\n\t\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: verify issue: %w\", issueID, label, err)\n\t\t}\n\t\tif count == 0 {\n\t\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: issue does not exist\", issueID, label)\n\t\t}\n\t\treturn nil\n\t}\n\tif err := r.events.Record(ctx, domain.Event{\n\t\tIssueID:  issueID,\n\t\tType:     types.EventLabelAdded,\n\t\tActor:    actor,\n\t\tNewValue: label,\n\t}, domain.RecordEventOpts{UseWispsTable: opts.UseWispsTable}); err != nil {\n\t\treturn err\n\t}\n\t// A label is part of the bead snapshot; the idempotent no-op path above\n\t// returns without writing and journals nothing.\n\treturn issueops.RecordEventInTx(ctx, r.runner, issueops.EventUpdate, issueID, actor)\n}\n\nfunc (r *labelSQLRepositoryImpl) Delete(ctx context.Context, issueID, label, actor string, opts domain.LabelOpts) error {\n\tif issueID == \"\" {","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/label.go#L55-L91","documentation":"Returned when INSERT IGNORE affected 0 rows and the verification query confirms the parent issue does not exist in the issues (or wisps) table. The library treats this as a caller error: you are adding a label to a nonexistent issue, so nothing is inserted and no event is journaled.","triggerScenarios":"Calling Insert with an issueID that was never created, was deleted, or an ID format mismatch (e.g. using a short prefix instead of the full ID); Insert into wisps mode when the issue lives in `issues` instead.","commonSituations":"Stale client cache holding a deleted issue ID; passing a wisp ID while UseWispsTable is false; race where the issue was removed between read and label insert; typos in hand-built IDs.","solutions":["Create the issue first, then insert the label","Verify the issue ID exists (e.g. `bd show <id>`) before labeling","Check UseWispsTable matches the table the issue actually resides in","Use the full canonical issue ID, not a prefix"],"exampleFix":"// before\nrepo.Insert(ctx, \"bd-abc\", \"bug\", opts) // ID may not exist\n// after\nif _, err := issueRepo.Get(ctx, \"bd-abc-1234\"); err != nil { return err }\nreturn repo.Insert(ctx, \"bd-abc-1234\", \"bug\", opts)","handlingStrategy":"validation","validationCode":"func issueExists(ctx context.Context, db *sql.DB, id string, wisps bool) (bool, error) {\n    t := \"issues\"; if wisps { t = \"wisps\" }\n    var n int\n    if err := db.QueryRowContext(ctx, \"SELECT COUNT(*) FROM \"+t+\" WHERE id = ?\", id).Scan(&n); err != nil { return false, err }\n    return n > 0, nil\n}","typeGuard":null,"tryCatchPattern":"if err := repo.Insert(ctx, issueID, label, opts); err != nil {\n    if strings.Contains(err.Error(), \"issue does not exist\") {\n        return fmt.Errorf(\"cannot label %s: create the issue first\", issueID)\n    }\n    return err\n}","preventionTips":["Always create the issue before adding labels","Use full canonical issue IDs from the API, never prefixes","Refresh stale local caches of issue IDs","Set UseWispsTable correctly for wisps vs issues"],"tags":["database","referential-integrity","missing-record"],"backgroundTag":"parent-record-not-found","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}