gastownhall/beads · error
search %s (id scan): scan: %w
Error message
search %s (id scan): scan: %w
What it means
Raised when rows.Scan fails while reading a single id string column during scanFilterIDs. Because the query selects exactly one column into one string, failures usually mean a NULL id (schema corruption) or a driver conversion problem rather than column-count mismatch.
Source
Thrown at internal/storage/domain/db/issue_search.go:312
func (r *issueSQLRepositoryImpl) scanFilterIDs(ctx context.Context, selectKw, fromSQL, whereSQL string, args []any, filter types.IssueFilter, tables filterTables) ([]string, bool, error) {
orderBy := orderBySQL(filter.SortBy, filter.SortDesc, tables.Main)
window := searchWindowForFilter(filter)
//nolint:gosec // G201: SQL fragments from fixed table names and parameterized filters.
idQuery := fmt.Sprintf(`%s%s.id FROM %s %s %s %s`,
selectKw, tables.Main, fromSQL, whereSQL, orderBy, window.sql)
rows, err := r.runner.QueryContext(ctx, idQuery, args...)
if err != nil {
return nil, false, fmt.Errorf("search %s (id scan): %w", tables.Main, err)
}
defer func() { _ = rows.Close() }()
var ids []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
return nil, false, fmt.Errorf("search %s (id scan): scan: %w", tables.Main, err)
}
ids = append(ids, id)
}
if err := rows.Err(); err != nil {
return nil, false, fmt.Errorf("search %s (id scan): rows: %w", tables.Main, err)
}
sortRowsGoSide(ids, func(id string) string { return id }, filter.SortBy, filter.SortDesc)
return finishWindow(ids, window)
}
func (r *issueSQLRepositoryImpl) hydrateIssues(ctx context.Context, issues []*types.Issue, tables filterTables, includeDeps bool, skipLabels bool) error {
if len(issues) == 0 {
return nil
}
ids := make([]string, len(issues))
for i, issue := range issues {View on GitHub (pinned to 71377f2769)
Solutions
- Find the row with the NULL/malformed id: SELECT * FROM issues WHERE id IS NULL.
- Repair or delete the corrupt row(s); restore from Dolt history if writes were conflicting.
- Run `bd doctor` for integrity validation after repair.
- Restore the database from backup if corruption is widespread.
Example fix
// before // issues table contains a row with NULL id -> scan into string fails // after DELETE FROM issues WHERE id IS NULL; -- or restore from dolt history
Defensive patterns
Strategy: validation
Validate before calling
// integrity check for NULL primary ids before search-heavy workflows
rows := query("SELECT COUNT(*) FROM issues WHERE id IS NULL OR id = ''")
if count > 0 { run bd doctor / restore from dolt history } Type guard
func isIDScanTypeError(err error) bool {
return err != nil && strings.Contains(err.Error(), "(id scan): scan: ")
} Try / catch
page, err := store.Search(ctx, q, filter)
if err != nil && isIDScanTypeError(err) {
return fmt.Errorf("corrupt issue rows (NULL id); restore from history or `bd doctor`: %w", err)
} Prevention
- Never mutate primary keys with external SQL tools.
- Resolve Dolt merge conflicts before operating on the database.
- Schedule periodic `bd doctor` integrity checks.
- Back up .beads before risky bulk operations.
When it happens
Trigger: The id-only query returns a row whose id column is NULL or non-text — typically from external edits, partial writes, or replication conflicts in Dolt that left a row without a primary id value.
Common situations: Manual SQL edits to the .beads database; a failed/crashed write leaving a partially inserted row; Dolt merge conflicts introducing NULL primary keys.
Related errors
- scan dependency source: %w
- scan dependency target: %w
- %s: %w
- failed to scan federation peer: %w
- db: ChildCounterSQLRepository.NextChildID: scan: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/95b7cf0ca7c306c6.
Report an issue: GitHub.