gastownhall/beads · error
scan dependent: %w
Error message
scan dependent: %w
What it means
While iterating dependents rows in FindAllDependentsInTx, rows.Scan into a single string column (issue_id) failed. This means the result row could not be decoded into a string — usually a driver-level decode error or an unexpected column shape, not a data problem.
Source
Thrown at internal/storage/issueops/delete.go:442
toProcess = toProcess[batchEnd:]
inClause, args := buildSQLInClause(batch)
for _, depTable := range []string{"dependencies", "wisp_dependencies"} {
rows, err := tx.QueryContext(ctx,
fmt.Sprintf(`SELECT issue_id FROM %s WHERE %s`, depTable, depTargetIn("", inClause)),
args...)
if err != nil {
if optionalBlockedTable(depTable) && isTableNotExistError(err) {
continue
}
return nil, fmt.Errorf("query dependents for batch from %s: %w", depTable, err)
}
for rows.Next() {
var depID string
if err := rows.Scan(&depID); err != nil {
_ = rows.Close()
return nil, fmt.Errorf("scan dependent: %w", err)
}
if !result[depID] {
result[depID] = true
toProcess = append(toProcess, depID)
}
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate dependents for batch from %s: %w", depTable, err)
}
}
}
return result, nil
}
//nolint:gosec // G201: table is selected by callers from fixed issue/wisp auxiliary tables.
func CountRowsForIssueIDsInTx(ctx context.Context, tx DBTX, table string, ids []string) (int, error) {View on GitHub (pinned to 71377f2769)
Solutions
- Find and repair the offending row: SELECT * FROM dependencies WHERE issue_id IS NULL and fix or delete it
- Re-run bd doctor / integrity checks to detect corrupt dependency rows
- Re-import or re-sync the dependency data if corruption came from a bad sync
- Update the storage driver if a type-mismatch bug is implicated
Example fix
-- before (corrupt row)
INSERT INTO dependencies (issue_id, depends_on_id) VALUES (NULL, 'bd-1');
-- after
INSERT INTO dependencies (issue_id, depends_on_id) VALUES ('bd-2', 'bd-1'); Defensive patterns
Strategy: validation
Validate before calling
// detect corrupt dependency rows before deleting
rows, _ := db.Query("SELECT issue_id FROM dependencies WHERE issue_id IS NULL")
// any result => repair rows before cascade delete Try / catch
_, err := DeleteIssuesInTx(ctx, tx, ids, WithCascade())
if err != nil && strings.Contains(err.Error(), "scan dependent:") {
repairNullDependencyRows(db) // fix or remove bad rows, then retry
return retry(ctx, ids)
}
return err Prevention
- Validate imported/synced dependency rows (no NULL issue_id)
- Run integrity checks after imports and syncs
- Keep the storage driver up to date
When it happens
Trigger: Cascade traversal (ResolveDeletionSetInTx → FindAllDependentsInTx) where the SELECT returns a row whose value cannot scan into a string — e.g. NULL issue_id in a corrupted dependency row, or a driver type mismatch.
Common situations: Corrupted dependency rows after a failed import/sync inserting NULL or non-string issue_id values; driver version mismatch producing unexpected column types.
Related errors
- failed to scan issue id: %w
- get next child ID: scan child row: %w
- dependency graph: scan %s: %w
- ErrScan
- failed to scan dependency keys: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/e3c34903ec78e7c0.
Report an issue: GitHub.