{"record":{"id":"4b5742a4c42752b9","repo":"gastownhall/beads","slug":"get-dependency-counts-scan-dependent-w","errorCode":null,"errorMessage":"get dependency counts: scan dependent: %w","messagePattern":"get dependency counts: scan dependent: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":510,"sourceCode":"\t\t\t//nolint:gosec // G201: depTable is hardcoded and inClause contains only ? placeholders.\n\t\t\tblockingRows, err := tx.QueryContext(ctx, fmt.Sprintf(`\n\t\t\t\tSELECT %s AS depends_on_id, COUNT(*) as cnt\n\t\t\t\tFROM %s\n\t\t\t\tWHERE %s AND type = 'blocks'\n\t\t\t\tGROUP BY %s\n\t\t\t`, DepTargetExpr, depTable, depTargetIn(\"\", inClause), DepTargetExpr), args...)\n\t\t\tif err != nil {\n\t\t\t\tif optionalBlockedTable(depTable) && isTableNotExistError(err) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"get dependency counts (dependents from %s): %w\", depTable, err)\n\t\t\t}\n\t\t\tfor blockingRows.Next() {\n\t\t\t\tvar id string\n\t\t\t\tvar cnt int\n\t\t\t\tif err := blockingRows.Scan(&id, &cnt); err != nil {\n\t\t\t\t\t_ = blockingRows.Close()\n\t\t\t\t\treturn nil, fmt.Errorf(\"get dependency counts: scan dependent: %w\", err)\n\t\t\t\t}\n\t\t\t\tif c, ok := result[id]; ok {\n\t\t\t\t\tc.DependentCount += cnt\n\t\t\t\t}\n\t\t\t}\n\t\t\t_ = blockingRows.Close()\n\t\t\tif err := blockingRows.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"get dependency counts: dependent rows: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\n// GetBlockingInfoForIssuesInTx returns blocking dependency records for a set of issue IDs.\n// Returns three maps:\n//   - blockedByMap: issueID -> list of IDs blocking it","sourceCodeStart":492,"sourceCodeEnd":528,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L492-L528","documentation":"Returned by GetDependencyCountsInTx when a row from the 'dependents counts' aggregate query (SELECT depends_on_id, COUNT(*) ... GROUP BY depends_on_id) cannot be scanned into (string, int). The wrapped error identifies the exact scan failure, typically a column type or nullability mismatch against the dependencies table.","triggerScenarios":"Calling GetDependencyCountsInTx against a schema where depends_on_id (via DepTargetExpr) or the COUNT column returns NULL or an unexpected type — e.g. rows hand-inserted with NULL depends_on_id, or a table altered to a type the driver cannot convert to string.","commonSituations":"Manual SQL edits inserting NULL depends_on_id rows; schema drift after partial migration; driver version incompatibilities changing type mapping; corrupted rows in a Dolt database restored from a bad backup.","solutions":["Read the wrapped scan error to find which column/value failed and locate the offending row.","Delete or repair rows with NULL depends_on_id in dependencies/wisp_dependencies (SELECT ... WHERE depends_on_id IS NULL).","Re-run schema migration (bd doctor / migrations) to restore expected column types and nullability.","Restore from a known-good backup if rows are corrupted.","Ensure driver and server versions match to avoid type-conversion differences."],"exampleFix":"// before: NULL depends_on_id rows break the scan\nSELECT * FROM dependencies WHERE depends_on_id IS NULL;\n\n// after: remove or repair offending rows\nDELETE FROM dependencies WHERE depends_on_id IS NULL;","handlingStrategy":"validation","validationCode":"// Go: detect rows that will fail the scan beforehand\nrows, err := tx.QueryContext(ctx,\n    \"SELECT depends_on_id FROM dependencies WHERE depends_on_id IS NULL\")\nif err != nil { return err }\ndefer rows.Close()\nif rows.Next() {\n    return fmt.Errorf(\"dependencies has NULL depends_on_id rows; repair before querying\")\n}","typeGuard":"func isScanError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"scan dependent\")\n}","tryCatchPattern":"counts, err := GetDependencyCountsInTx(ctx, tx, ids)\nif err != nil && strings.Contains(err.Error(), \"scan dependent\") {\n    // repair NULL rows, then retry once\n    if _, fixErr := tx.ExecContext(ctx,\n        \"DELETE FROM dependencies WHERE depends_on_id IS NULL\"); fixErr != nil {\n        return fixErr\n    }\n    counts, err = GetDependencyCountsInTx(ctx, tx, ids)\n}","preventionTips":["Add NOT NULL constraints on depends_on_id and issue_id columns.","Validate imported data for NULLs before inserting into dependency tables.","Run bd doctor after manual database surgery or restores.","Avoid direct SQL edits; use bd commands to mutate dependencies."],"tags":["database","scan-error","null-value","schema-mismatch"],"backgroundTag":"sql-row-scan-type-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}