{"record":{"id":"ef7b9f9f5ae99fdf","repo":"gastownhall/beads","slug":"db-labelsqlrepository-list-scan-w","errorCode":null,"errorMessage":"db: LabelSQLRepository.List: scan: %w","messagePattern":"db: LabelSQLRepository\\.List: scan: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/label.go","lineNumber":143,"sourceCode":"\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) {\n\tresult := make(map[string][]string)\n\tif len(issueIDs) == 0 {\n\t\treturn result, nil\n\t}\n\tplaceholders := make([]string, len(issueIDs))\n\targs := make([]any, len(issueIDs))\n\tfor i, id := range issueIDs {\n\t\tplaceholders[i] = \"?\"","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/label.go#L125-L161","documentation":"LabelSQLRepository.List failed while scanning a row from the labels table into a string. database/sql's rows.Scan returned an error for the current row, and the repository wraps it with this context. It means the query succeeded but a row could not be converted into the destination type.","triggerScenarios":"Calling List when a row value is not scannable into *string — e.g. a NULL in the label column, or a driver returning an unexpected type for the label column.","commonSituations":"Schema drift after a migration changed the label column to nullable or to a non-string type; a custom or mocked driver returning exotic types (e.g. []byte with non-UTF8 data handled unexpectedly); using an embedded/Dolt driver with different NULL handling.","solutions":["Inspect the wrapped error via errors.Unwrap/As to see the exact scan failure (unsupported Scan, converting NULL to string, etc.)","Check the labels table schema: the label column should be NOT NULL and text-typed; migrate any NULL rows","If NULLs are expected, alter the query to use COALESCE(label, '') or scan into a *string/sql.NullString","Verify the driver in use matches the schema (e.g. re-run schema migrations for the embedded Dolt database)"],"exampleFix":"// before\nvar label string\nif err := rows.Scan(&label); err != nil { ... }\n// after\nvar label sql.NullString\nif err := rows.Scan(&label); err != nil { ... }\nif label.Valid { out = append(out, label.String) }","handlingStrategy":"try-catch","validationCode":"// before calling List, verify schema\nvar notNull, dtype string\nerr := rawRepo.QueryRow(ctx, `SELECT COUNT(*) FROM information_schema.columns WHERE table_name='issue_labels' AND column_name='label' AND is_nullable='NO'`).Scan(&notNull)\n// or check migrations ran before opening repos","typeGuard":"func isScanErr(err error) bool {\n    var s *fmt.ScanError // or check strings.Contains(err.Error(), \"Scan\")\n    return err != nil && strings.Contains(err.Error(), \"unsupported Scan\")\n}","tryCatchPattern":"labels, err := repo.List(ctx, opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"scan: \") {\n        // inspect cause\n        log.Printf(\"label scan failed: %v\", errors.Unwrap(err))\n    }\n    return err\n}","preventionTips":["Keep label column NOT NULL in migrations","Use COALESCE for nullable text columns","Run schema migrations at startup before repository use","Test repositories against the real driver, not only mocks"],"tags":["go","database","sql","scan"],"backgroundTag":"sql-row-scan-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}