{"record":{"id":"446b7cd5e1332c84","repo":"gastownhall/beads","slug":"get-dependency-records-scan-w","errorCode":null,"errorMessage":"get dependency records: scan: %w","messagePattern":"get dependency records: scan: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":126,"sourceCode":"\t\tbatch := ids[start:end]\n\t\tplaceholders := make([]string, len(batch))\n\t\targs := make([]any, len(batch))\n\t\tfor i, id := range batch {\n\t\t\tplaceholders[i] = \"?\"\n\t\t\targs[i] = id\n\t\t}\n\t\trows, err := tx.QueryContext(ctx, fmt.Sprintf(\n\t\t\t`SELECT issue_id, %s AS depends_on_id, type, created_at, created_by, metadata, thread_id\n\t\t\t FROM %s WHERE issue_id IN (%s) ORDER BY issue_id, depends_on_id, type, id`,\n\t\t\tDepTargetExpr, depTable, strings.Join(placeholders, \",\")), args...)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"get dependency records from %s: %w\", depTable, err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tdep, scanErr := scanDependencyRow(rows)\n\t\t\tif scanErr != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn fmt.Errorf(\"get dependency records: scan: %w\", scanErr)\n\t\t\t}\n\t\t\tresult[dep.IssueID] = append(result[dep.IssueID], dep)\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn fmt.Errorf(\"get dependency records: rows: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// GetDependentRecordsForIssuesInTx returns raw dependency rows keyed by TARGET\n// id: for each id in targetIDs, the rows whose target is that id — its INCOMING\n// edges, i.e. its dependents — spanning BOTH the durable and wisp dependency\n// tables and applying NO type filter or visibility policy (the caller filters\n// at hydration). It is the batched, target-keyed mirror of the source-keyed\n// GetDependencyRecordsForIssuesInTx: one query per table per batch of\n// queryBatchSize target ids, so cost is O(1 + N/queryBatchSize) round-trips per","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L108-L144","documentation":"During row iteration in getDependencyRecordsIntoFromTable, scanDependencyRow failed to decode a row, so the loop closes the rows and aborts with this wrapped scan error. It means one row's column count/types/NULLs didn't match the dependency struct expectations in the per-issue query path — the query succeeded but a result row was unreadable.","triggerScenarios":"scanDependencyRow erroring on a row fetched by GetDependencyRecordsForIssuesInTx or GetDependencyRecordsForIssuesFromTableInTx — unexpected NULL in created_by/metadata/thread_id, or a driver type mismatch on created_at for rows in either dependency table.","commonSituations":"Mixed-version rows (older writer schema vs current scanner); driver upgrade changing scan type behavior; rows written by an external tool directly into the dependency tables.","solutions":["Read the wrapped scan error to find the failing column, then inspect the offending row in the named table.","Harden scanDependencyRow for the observed NULL/type shape (sql.NullString etc.) — the shared scanner is the single fix point for both query paths.","Bring rows written by an older schema forward through the driver's migration path instead of patching rows ad hoc."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"recs, err := GetDependencyRecordsForIssuesInTx(ctx, tx, ids)\nif err != nil {\n    if strings.Contains(err.Error(), \"get dependency records: scan\") {\n        // row-shape issue in the per-issue path; inspect the failing row/column\n    }\n    return err\n}","preventionTips":["Keep the shared scanDependencyRow NULL-tolerant for optional columns.","Run mixed-version read tests after schema or driver changes.","Avoid external writes to dependency tables that could produce unexpected row shapes."],"tags":["go","database","sql","row-scan","null-handling"],"backgroundTag":"row-scan-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}