{"record":{"id":"abc915a79f03af03","repo":"gastownhall/beads","slug":"get-issues-by-ids-labels-from-s-w","errorCode":null,"errorMessage":"get issues by IDs: labels from %s: %w","messagePattern":"get issues by IDs: labels from (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependencies.go","lineNumber":1071,"sourceCode":"\t\t\t\tif scanErr != nil {\n\t\t\t\t\t_ = rows.Close()\n\t\t\t\t\treturn nil, fmt.Errorf(\"get issues by IDs: scan: %w\", scanErr)\n\t\t\t\t}\n\t\t\t\tallIssues = append(allIssues, issue)\n\t\t\t\tissueMap[issue.ID] = issue\n\t\t\t}\n\t\t\t_ = rows.Close()\n\t\t\tif err := rows.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"get issues by IDs: rows: %w\", err)\n\t\t\t}\n\n\t\t\t// Hydrate labels.\n\t\t\tif len(issueMap) > 0 {\n\t\t\t\tlabelRows, err := tx.QueryContext(ctx, fmt.Sprintf(\n\t\t\t\t\t`SELECT issue_id, label FROM %s WHERE issue_id IN (%s) ORDER BY issue_id, label`,\n\t\t\t\t\tpair.labelTbl, inClause), args...)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"get issues by IDs: labels from %s: %w\", pair.labelTbl, err)\n\t\t\t\t}\n\t\t\t\tfor labelRows.Next() {\n\t\t\t\t\tvar issueID, label string\n\t\t\t\t\tif scanErr := labelRows.Scan(&issueID, &label); scanErr != nil {\n\t\t\t\t\t\t_ = labelRows.Close()\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"get issues by IDs: scan label: %w\", scanErr)\n\t\t\t\t\t}\n\t\t\t\t\tif issue, ok := issueMap[issueID]; ok {\n\t\t\t\t\t\tissue.Labels = append(issue.Labels, label)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t_ = labelRows.Close()\n\t\t\t\tif err := labelRows.Err(); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"get issues by IDs: label rows: %w\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}","sourceCodeStart":1053,"sourceCodeEnd":1089,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependencies.go#L1053-L1089","documentation":"Wraps a QueryContext error while hydrating labels for the fetched issues in GetIssuesByIDsInTx. The issue rows loaded fine but the follow-up SELECT against the label table (permanent or wisp labels) failed.","triggerScenarios":"The `SELECT issue_id, label FROM <labels|wisp_labels> WHERE issue_id IN (...)` query errors — missing label table, driver error, connection failure, or oversized IN clause.","commonSituations":"Partial migrations where wisp_labels was not created; connection drop between the issue query and label query; very large ID lists hitting placeholder limits.","solutions":["Check the wrapped driver error and confirm the named label table exists (migrations)","Batch large ID lists to stay under placeholder limits","Retry on transient errors; the operation is read-only and safe to re-run","Verify driver/schema version alignment after upgrades"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm both label tables exist before ID-batch fetches:\nfor _, tbl := range []string{\"labels\", \"wisp_labels\"} {\n    var n int\n    err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name = ?`, tbl).Scan(&n)\n    if err != nil || n == 0 { return fmt.Errorf(\"missing label table %s; run migrations\", tbl) }\n}","typeGuard":null,"tryCatchPattern":"issues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)\nif err != nil && strings.Contains(err.Error(), \"labels from\") {\n    if isMissingTable(err) { return runMigrationsThenRetry(ctx) }\n    if isTransientDBError(err) { issues, err = GetIssuesByIDsInTx(ctx, tx, ids, nil) }\n    if err != nil { return err }\n}","preventionTips":["Run full migrations (wisp_labels included), not partial ones","Batch ID lists to avoid placeholder overflow on the label query","Treat label hydration as re-runnable — safe to retry read-only fetches","Keep driver version aligned with the SQL fragments in the code"],"tags":["database","sql","labels","go"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}