{"record":{"id":"ff25144b0b5ef4bd","repo":"gastownhall/beads","slug":"get-issues-by-ids-scan-w","errorCode":null,"errorMessage":"get issues by IDs: scan: %w","messagePattern":"get issues by IDs: scan: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependencies.go","lineNumber":1055,"sourceCode":"\t\t\targs := make([]any, len(batch))\n\t\t\tfor i, id := range batch {\n\t\t\t\tplaceholders[i] = \"?\"\n\t\t\t\targs[i] = id\n\t\t\t}\n\t\t\tinClause := strings.Join(placeholders, \",\")\n\n\t\t\trows, err := tx.QueryContext(ctx, fmt.Sprintf(\n\t\t\t\t`SELECT %s FROM %s %s WHERE id IN (%s)`,\n\t\t\t\tIssueSelectColumns, pair.table, sqlbuild.LeaseJoin(pair.table), inClause), args...)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"get issues by IDs from %s: %w\", pair.table, err)\n\t\t\t}\n\t\t\tissueMap := make(map[string]*types.Issue)\n\t\t\tfor rows.Next() {\n\t\t\t\tissue, scanErr := ScanIssueFrom(rows)\n\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() {","sourceCodeStart":1037,"sourceCodeEnd":1073,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependencies.go#L1037-L1073","documentation":"Wraps a row-scanning failure (ScanIssueFrom) while decoding an issue row from the ID-batch query in GetIssuesByIDsInTx. It means the query succeeded but a row's columns could not be mapped into types.Issue.","triggerScenarios":"ScanIssueFrom fails on a row inside the `for rows.Next()` loop — column count/type mismatch between IssueSelectColumns and the struct, NULL in a non-nullable field, or corrupt data in the row.","commonSituations":"Schema drift: a migration added/removed/renamed a column but the scan code and DB are out of sync; manually edited rows with NULLs where the scan expects values; mixed table layouts between issues and wisps tables.","solutions":["Run pending migrations so the schema matches the scanner's expectations","Check which column fails to scan in the wrapped error and inspect that row's data","Rebuild/reindex corrupted rows or restore from backup if data is malformed","Ensure the binary and schema are from the same version (no partial upgrade)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before upgrading, verify schema matches the binary's expected columns:\n// Compare IssueSelectColumns against the live table schema in a preflight check.\ncols, err := db.QueryContext(ctx, `PRAGMA table_info(issues)`) // or driver equivalent\n// Ensure no NOT-NULL-expected column is nullable in practice; fix data first.","typeGuard":null,"tryCatchPattern":"issues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)\nif err != nil && strings.Contains(err.Error(), \"get issues by IDs: scan\") {\n    // Do NOT retry — scan errors are deterministic (schema/data drift).\n    return fmt.Errorf(\"schema or data mismatch, run migrations/integrity check: %w\", err)\n}","preventionTips":["Never skip migrations when upgrading; scan errors are schema-drift symptoms","Add a startup schema-version check against the binary's expectations","Avoid hand-editing issue rows directly; NULLs break scanners","Run integrity checks (bd doctor / DB check) after crashes"],"tags":["database","sql","scan","go"],"backgroundTag":"row-scan-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}