{"record":{"id":"f43e54bd761e7f16","repo":"gastownhall/beads","slug":"db-labelsqlrepository-list-s-w","errorCode":null,"errorMessage":"db: LabelSQLRepository.List %s: %w","messagePattern":"db: LabelSQLRepository\\.List (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/label.go","lineNumber":135,"sourceCode":"\t\tOldValue: label,\n\t}, domain.RecordEventOpts{UseWispsTable: opts.UseWispsTable}); err != nil {\n\t\treturn err\n\t}\n\treturn issueops.RecordEventInTx(ctx, r.runner, issueops.EventUpdate, issueID, actor)\n}\n\nfunc (r *labelSQLRepositoryImpl) List(ctx context.Context, issueID string, opts domain.LabelOpts) ([]string, error) {\n\tif issueID == \"\" {\n\t\treturn nil, fmt.Errorf(\"db: LabelSQLRepository.List: issueID must not be empty\")\n\t}\n\ttable := pickLabelTable(opts.UseWispsTable)\n\t//nolint:gosec // G201: table is one of two hardcoded constants\n\trows, err := r.runner.QueryContext(ctx,\n\t\tfmt.Sprintf(\"SELECT label FROM %s WHERE issue_id = ? ORDER BY label\", table),\n\t\tissueID,\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"db: LabelSQLRepository.List %s: %w\", issueID, err)\n\t}\n\tdefer rows.Close()\n\n\tvar out []string\n\tfor rows.Next() {\n\t\tvar label string\n\t\tif err := rows.Scan(&label); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"db: LabelSQLRepository.List: scan: %w\", err)\n\t\t}\n\t\tout = append(out, label)\n\t}\n\tif err := rows.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"db: LabelSQLRepository.List: rows: %w\", err)\n\t}\n\treturn out, nil\n}\n\nfunc (r *labelSQLRepositoryImpl) ListByIssueIDs(ctx context.Context, issueIDs []string, opts domain.LabelOpts) (map[string][]string, error) {","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/label.go#L117-L153","documentation":"Wraps failure of the SELECT label query in LabelSQLRepository.List, adding the issue ID. Thrown when the driver rejects the query (connection loss, missing table, permissions), preventing retrieval of an issue's labels.","triggerScenarios":"List called when the DB is unreachable, the labels table does not exist, or the query is cancelled via ctx (deadline/context cancellation).","commonSituations":"Context timeout cancelling a slow query; database not migrated so the labels table is absent; connection pool exhausted; wrong UseWispsTable mode for the current database.","solutions":["Inspect the wrapped driver error, especially context.DeadlineExceeded","Verify the labels table exists in this database","Check DB connectivity and pool configuration","Confirm UseWispsTable matches your storage mode"],"exampleFix":"// before\nctx := context.Background()\nlabels, err := repo.List(ctx, issueID, opts)\n// after\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\nlabels, err := repo.List(ctx, issueID, opts)\nif err != nil {\n    if errors.Is(err, context.DeadlineExceeded) { /* retry */ }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"if issueID == \"\" { return fmt.Errorf(\"issueID required\") }\nctx, cancel := context.WithTimeout(ctx, 5*time.Second); defer cancel()","typeGuard":"func isTimeout(err error) bool { return errors.Is(err, context.DeadlineExceeded) }","tryCatchPattern":"labels, err := repo.List(ctx, issueID, opts)\nif err != nil {\n    var sqle *mysql.MySQLError\n    switch {\n    case errors.Is(err, context.DeadlineExceeded):\n        return retry(ctx, issueID, opts)\n    case errors.As(err, &sqle) && sqle.Number == 1146:\n        return nil, fmt.Errorf(\"labels table missing; run migrations\")\n    }\n    return nil, err\n}","preventionTips":["Use context timeouts on repository reads","Run migrations so the labels tables exist","Confirm UseWispsTable matches the storage mode","Retry read queries on transient failures"],"tags":["database","sql","query","context-timeout"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}