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

  1. Check the wrapped driver error (%w) to identify the offending column/type
  2. Cast problematic columns in SQL (e.g. CAST(col AS CHAR) or JSON_EXTRACT) so the driver returns strings
  3. Retry the query if the cause was a transient connection drop
  4. 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

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


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/e96487f1d80f22ca. Report an issue: GitHub.