{"record":{"id":"0f79dc289ec20de0","repo":"gastownhall/beads","slug":"s-w-0f79dc","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/doctor/fix/label_whitespace.go","lineNumber":95,"sourceCode":"\n// Total returns the number of flagged rows across all three classes.\nfunc (a LabelWhitespaceAnomalies) Total() int {\n\treturn len(a.Untrimmed) + len(a.Blank) + len(a.Internal)\n}\n\n// ScanLabelWhitespace reports labels carrying whitespace damage in both label\n// tables. Tables absent from the schema are skipped; only tables with anomalies\n// appear in the result.\n//\n// Classification happens in Go rather than SQL so that tabs, newlines and\n// Unicode spaces are caught the same way strings.TrimSpace catches them —\n// a TRIM()-based predicate would silently miss them.\nfunc ScanLabelWhitespace(ctx context.Context, db *sql.DB) ([]LabelWhitespaceAnomalies, error) {\n\tvar out []LabelWhitespaceAnomalies\n\tfor _, table := range labelTables {\n\t\texists, err := labelTableExists(ctx, db, table)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%s: %w\", table, err)\n\t\t}\n\t\tif !exists {\n\t\t\tcontinue\n\t\t}\n\n\t\ta := LabelWhitespaceAnomalies{Table: table}\n\t\t//nolint:gosec // G201: table is a hardcoded constant, never user input.\n\t\trows, err := db.QueryContext(ctx, fmt.Sprintf(`SELECT issue_id, label FROM %s`, table))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%s: %w\", table, err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tvar issueID string\n\t\t\tvar label sql.NullString\n\t\t\tif err := rows.Scan(&issueID, &label); err != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn nil, fmt.Errorf(\"%s: %w\", table, err)\n\t\t\t}","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor/fix/label_whitespace.go#L77-L113","documentation":"ScanLabelWhitespace checks each label table for label values with leading/trailing whitespace; before querying it calls labelTableExists, and if that existence check errors the failure is wrapped as \"<table>: <cause>\". It means the scan could not even determine whether a label table exists — a database-level problem, not whitespace anomalies.","triggerScenarios":"Calling ScanLabelWhitespace when labelTableExists fails for a table: the schema-introspection query errors due to dropped connection, insufficient privileges to read information_schema/metadata, or driver errors against the Dolt server.","commonSituations":"Dolt server unreachable or restarted during `bd doctor`; DB user lacking permission to list tables; corrupted metadata after a failed migration.","solutions":["Verify database connectivity and server health, then re-run the label whitespace fix","Grant the DB user permission to read table metadata (information_schema)","Check Dolt server logs for the underlying metadata query error"],"exampleFix":"// before\nanomalies, err := fix.ScanLabelWhitespace(ctx, db) // labels: driver: bad connection\n// after: preflight the connection\nif err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"database unreachable: %w\", err)\n}\nanomalies, err := fix.ScanLabelWhitespace(ctx, db)","handlingStrategy":"try-catch","validationCode":"if err := db.PingContext(ctx); err != nil {\n\treturn fmt.Errorf(\"DB unreachable before label whitespace scan: %w\", err)\n}\n// Confirm metadata access works\nif _, err := db.QueryContext(ctx, `SHOW TABLES`); err != nil {\n\treturn fmt.Errorf(\"cannot read table metadata: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"anomalies, err := fix.ScanLabelWhitespace(ctx, db)\nif err != nil {\n\treturn fmt.Errorf(\"label whitespace scan aborted (no changes made): %w\", err)\n}","preventionTips":["Ping the DB and verify metadata access before running doctor scans","Grant the DB user permission to inspect table metadata","Avoid scanning during server restarts or schema migrations"],"tags":["database","sql","scan","doctor"],"backgroundTag":"table-existence-check-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}