gastownhall/beads · error
failed to scan stale issue id: %w
Error message
failed to scan stale issue id: %w
What it means
GetStaleIssuesInTx scans a single string (the issue id) from each row of the stale-issues SELECT; this error wraps a rows.Scan failure. With a literal single-column 'SELECT id' this almost always means the row value was NULL (sql.Scan into string fails) or the driver returned an unexpected column type.
Source
Thrown at internal/storage/issueops/stale.go:77
if filter.Limit > 0 {
query += fmt.Sprintf(" LIMIT %d", filter.Limit)
}
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("failed to get stale issues: %w", err)
}
// Collect IDs first, then batch-fetch full issues.
// Close rows explicitly before the nested fetch — MySQL/Dolt drivers
// can't handle multiple active result sets on one connection.
var ids []string
for rows.Next() {
var id string
if err := rows.Scan(&id); err != nil {
rows.Close()
return nil, fmt.Errorf("failed to scan stale issue id: %w", err)
}
ids = append(ids, id)
}
if err := rows.Err(); err != nil {
rows.Close()
return nil, fmt.Errorf("stale issues rows: %w", err)
}
rows.Close()
if len(ids) == 0 {
return nil, nil
}
// GetIssuesByIDsInTx returns issues in arbitrary order (WHERE IN),
// so re-order to preserve the updated_at ASC ordering from the query.
issues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)
if err != nil {
return nil, errView on GitHub (pinned to 71377f2769)
Solutions
- Inspect the issues table for rows with NULL ids (SELECT COUNT(*) FROM issues WHERE id IS NULL) and repair or delete them.
- If the schema was customized, restore the standard schema so id is a non-null primary key.
- Check the driver version (Dolt/MySQL) matches what the library expects; upgrade or pin it.
- If the error persists, capture the wrapped error text to confirm whether it is a NULL-conversion error (sql: Scan error ... converting NULL to string).
Example fix
// before // NULL ids present in corrupted table // after DELETE FROM issues WHERE id IS NULL; -- repair corrupted rows
Defensive patterns
Strategy: validation
Validate before calling
// detect NULL ids in the issues table before scanning
var nulls int
_ = tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM issues WHERE id IS NULL`).Scan(&nulls)
if nulls > 0 { return fmt.Errorf("%d issues rows have NULL ids; repair database", nulls) } Try / catch
ids, err := issueops.GetStaleIssuesInTx(ctx, tx, filter)
if err != nil && strings.Contains(err.Error(), "converting NULL to string") {
return fmt.Errorf("corrupt issues table (NULL id); run repair: %w", err)
} Prevention
- Never hand-edit the issues table; use bd commands
- Run integrity checks after crashes or forced kills
- Keep the driver version aligned with the library's expectations
- Back up the database before schema experiments
When it happens
Trigger: A row in issues has a NULL id column (corrupted data or an aliased/modified query), or the driver returns an id in a type database/sql cannot convert into a Go string.
Common situations: A corrupted or manually edited Dolt/MySQL database where issues.id is NULL; running against a schema variant where id is not the first/only returned column; driver version mismatches altering scan behavior.
Related errors
- failed to scan dolt_status: %w
- scan dirty config key: %w
- db: ChildCounterSQLRepository.NextChildID: scan: %w
- db: CommentSQLRepository.CountsByIssueIDs: scan: %w
- db: CommentSQLRepository.ListByIssueIDs: scan: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1e2e37457b89e048.
Report an issue: GitHub.