gastownhall/beads · error
journal: scan dependency removal from %s: %w
Error message
journal: scan dependency removal from %s: %w
What it means
While scanning dependency-removal edges from one table into journalDependencyEdge (source, target, kind, metadata), rows.Scan failed. This wraps column-count/type mismatches between the queried table's projection and the four-field scanner. The rows are explicitly closed before returning, so the error path is clean.
Source
Thrown at internal/storage/issueops/journal_dependencies.go:99
inClause, args := buildSQLInClause(ids[start:end])
queryArgs := append(append([]any{}, args...), args...)
//nolint:gosec // table is validated above and inClause contains only placeholders.
rows, err := tx.QueryContext(ctx, fmt.Sprintf(`
SELECT issue_id, %s AS target, type, metadata
FROM %s
WHERE issue_id IN (%s) OR %s IN (%s)
`, DepTargetExpr, table, inClause, DepTargetExpr, inClause), queryArgs...)
if err != nil {
if optionalBlockedTable(table) && isTableNotExistError(err) {
continue
}
return nil, fmt.Errorf("journal: query dependency removals from %s: %w", table, err)
}
for rows.Next() {
var edge journalDependencyEdge
if err := rows.Scan(&edge.source, &edge.target, &edge.kind, &edge.metadata); err != nil {
_ = rows.Close()
return nil, fmt.Errorf("journal: scan dependency removal from %s: %w", table, err)
}
byKey[dependencyEdgeKey(edge)] = edge
}
if err := rows.Err(); err != nil {
_ = rows.Close()
return nil, fmt.Errorf("journal: iterate dependency removals from %s: %w", table, err)
}
if err := rows.Close(); err != nil {
return nil, fmt.Errorf("journal: close dependency removals from %s: %w", table, err)
}
}
return sortedDependencyEdges(byKey), nil
}
func dependencyEdgeKey(edge journalDependencyEdge) string {
return edge.source + "\x00" + edge.target + "\x00" + edge.kind + "\x00" + edge.metadata
}
View on GitHub (pinned to 71377f2769)
Solutions
- Run migrations/`bd doctor` to reconcile the dependency table schema with the expected projection.
- Diff the table's columns against the SELECT in dependencyEdgesInTableForIssueIDsInTx and ALTER to restore the expected shape.
- Repair rows with unexpected NULLs in source/target/kind columns.
- Align the driver version with the app's tested version.
Example fix
// before ALTER TABLE issue_dependencies CHANGE kind dep_type VARCHAR(32); -- scanner expects `kind` // after ALTER TABLE issue_dependencies CHANGE dep_type kind VARCHAR(32); -- restore expected column name
Defensive patterns
Strategy: validation
Validate before calling
cols, _ := db.Query("SHOW COLUMNS FROM issue_dependencies")
want := map[string]bool{"source": true, "target": true, "kind": true, "metadata": true}
for cols.Next() { var c, t, null, key, extra string; _ = cols.Scan(&c, &t, &null, &key, &extra); delete(want, c) }
if len(want) > 0 { return fmt.Errorf("dependency table schema drift, missing: %v", want) } Try / catch
if err != nil && strings.Contains(err.Error(), "journal: scan dependency removal from") {
return fmt.Errorf("dependency table schema drifted vs scanner; reconcile via migrations: %w", err)
} Prevention
- Let migrations own dependency-table schema; no manual renames.
- Restore only matching-version backups.
- Check for unexpected NULLs in source/target/kind after imports.
- Pin driver versions so TEXT/JSON scanning behavior is stable.
When it happens
Trigger: RecordDependencyRemovalsForTableInTx / dependencyEdgesForIssueIDsInTx encountering rows whose shape differs from the SELECT: schema drift on a dependency table (renamed/dropped/extra columns), NULL in a column scanned into a non-nullable field, or a driver returning unexpected types for kind/metadata.
Common situations: Manually altered dependency tables; restoring tables from an older backup with a different schema; a driver version changing how TEXT/JSON metadata is returned.
Related errors
- journal: scan row: %w
- journal: query dependency removals from %s: %w
- failed to remove relates-to %s -> %s: %w
- failed to get dependencies for %s: %w
- add deps: classify sources: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/098708e27d47c439.
Report an issue: GitHub.