{"record":{"id":"dd096fd8e146ff15","repo":"gastownhall/beads","slug":"get-dependent-records-scan-w","errorCode":null,"errorMessage":"get dependent records: scan: %w","messagePattern":"get dependent records: scan: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":201,"sourceCode":"\t\tbatch := targetIDs[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 id, issue_id, %s AS depends_on_id, type, created_at, created_by, metadata, thread_id\n\t\t\t FROM %s WHERE %s ORDER BY %s`,\n\t\t\tDepTargetExpr, depTable, depTargetIn(\"\", strings.Join(placeholders, \",\")), DepTargetExpr), args...)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"get dependent records from %s: %w\", depTable, err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tdep, scanErr := scanDependentRow(rows)\n\t\t\tif scanErr != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn fmt.Errorf(\"get dependent records: scan: %w\", scanErr)\n\t\t\t}\n\t\t\t// De-dup by row id (depid): the wisp copy of a promoted edge carries\n\t\t\t// the same id as the durable copy scanned first, so skip the repeat.\n\t\t\tif seen[dep.ID] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tseen[dep.ID] = true\n\t\t\tresult[dep.DependsOnID] = append(result[dep.DependsOnID], dep)\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn fmt.Errorf(\"get dependent records: rows: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Target-keyed dependents-read bounds. A raw read has no consumer to apply a","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L183-L219","documentation":"This error is returned when scanDependentRow fails while iterating rows of dependent dependency records — the row's columns could not be scanned into types.Dependency (id, issue_id, depends_on_id, type, created_at, created_by, metadata, thread_id). It indicates a shape mismatch between the stored row and the Go scan targets, not a query failure.","triggerScenarios":"A dependency row contains a NULL in a non-nullable scanned column, a created_at value the driver cannot parse into sql.NullTime, a column type change after a schema migration, or extra/missing columns from a divergent table schema.","commonSituations":"Manual schema edits or hand-imported rows with NULL issue_id/type; restoring a database from a different beads version; driver type coercion differences (e.g. text vs datetime) after switching storage backends.","solutions":["Read the wrapped sql scan error to identify which column failed.","Inspect the offending row(s) in the dependency table for NULLs or malformed values (especially created_at, issue_id, type).","Repair or delete the malformed rows; ensure columns declared NOT NULL stay that way.","Re-run migrations so the table schema matches the binary's expected shape.","Check for driver/version mismatch between the app and the database server."],"exampleFix":"// before: orphan row with NULL type crashes the whole read\nUPDATE dependencies SET type = 'relates-to' WHERE type IS NULL;\n// after: enforce at schema level\nALTER TABLE dependencies MODIFY type VARCHAR(64) NOT NULL;","handlingStrategy":"validation","validationCode":"// Check for rows that cannot be scanned before reading dependents\nrows, err := tx.QueryContext(ctx, \"SELECT id, issue_id, type FROM dependencies WHERE issue_id IS NULL OR type IS NULL\")\n// any returned row means the read will fail; repair it first","typeGuard":"func depRowScannable(id, issueID, depType sql.NullString, createdAt sql.NullTime) bool {\n    return id.Valid && issueID.Valid && depType.Valid && (!createdAt.Valid || !createdAt.Time.IsZero())\n}","tryCatchPattern":"deps, err := GetDependentRecordsForIssuesInTx(ctx, tx, targetIDs)\nvar scanErr interface{ Unwrap() error }\nif err != nil && strings.Contains(err.Error(), \"scan\") {\n    // identify and repair the malformed dependency row; do not retry blindly\n}","preventionTips":["Never hand-edit dependency rows; use library APIs","Add NOT NULL constraints on id, issue_id, depends_on target columns, type","After restoring backups, run a schema/data consistency check","Keep database driver and server versions aligned"],"tags":["database","sql-scan","data-integrity","storage"],"backgroundTag":"sql-scan-type-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}