gastownhall/beads · error
db: RawSQL Query: scan: %w
Error message
db: RawSQL Query: scan: %w
What it means
This error wraps a failure from sql.Rows.Scan inside RawSQLRepository.Query. Query scans each result row into a slice of `any` pointers sized to the column count; Scan fails when a driver value cannot be converted into the destination. Because destinations are `*any`, failures are almost always driver-level conversion or connection errors rather than type mismatches.
Source
Thrown at internal/storage/domain/db/raw_sql.go:40
if err != nil {
return nil, fmt.Errorf("db: RawSQL Query: %w", err)
}
defer rows.Close()
columns, err := rows.Columns()
if err != nil {
return nil, fmt.Errorf("db: RawSQL Query: columns: %w", err)
}
result := &domain.RawSQLResult{Columns: columns}
for rows.Next() {
values := make([]any, len(columns))
ptrs := make([]any, len(columns))
for i := range values {
ptrs[i] = &values[i]
}
if err := rows.Scan(ptrs...); err != nil {
return nil, fmt.Errorf("db: RawSQL Query: scan: %w", err)
}
for i, v := range values {
if b, ok := v.([]byte); ok {
values[i] = string(b)
}
}
result.Rows = append(result.Rows, values)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("db: RawSQL Query: rows: %w", err)
}
return result, nil
}
func (r *rawSQLRepositoryImpl) Exec(ctx context.Context, query string, args ...any) (int64, error) {
res, err := r.runner.ExecContext(ctx, query, args...)
if err != nil {
return 0, fmt.Errorf("db: RawSQL Exec: %w", err)View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped driver error (%w) to identify the offending column/type
- Cast problematic columns in SQL (e.g. CAST(col AS CHAR) or JSON_EXTRACT) so the driver returns strings
- Retry the query if the cause was a transient connection drop
- Upgrade the database driver to a version with broader type conversion support
Example fix
// before: SELECT meta FROM issues WHERE id = ? (meta is JSON) // after: SELECT CAST(meta AS CHAR) FROM issues WHERE id = ?
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure connection is alive before querying
if err := db.PingContext(ctx); err != nil { return fmt.Errorf("db unavailable: %w", err) } Type guard
func isScanError(err error) bool {
return err != nil && strings.Contains(err.Error(), "RawSQL Query: scan")
} Try / catch
res, err := repo.Query(ctx, q, args...)
if err != nil {
if isScanError(err) {
// rewrite query with CASTs for exotic column types, then retry once
}
return err
} Prevention
- CAST exotic column types (JSON, BLOB) to CHAR in raw SQL
- Keep queries bounded with LIMIT to avoid mid-stream drops
- Ping or health-check the DB before long raw queries
- Keep the driver up to date
When it happens
Trigger: Calling RawSQLRepository.Query with a query whose driver returns values the sql package cannot scan (e.g. unsupported column types, corrupt/invalid cell data, or a connection dropped mid-result-set).
Common situations: Running raw SQL against Dolt/MySQL with exotic column types (JSON, GEOMETRY) the driver struggles with; stale/canceled connections mid-iteration; context cancellation while the driver materializes a row.
Related errors
- %s: %w
- failed to scan federation peer: %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/e96487f1d80f22ca.
Report an issue: GitHub.