gastownhall/beads · error

db: RawSQL Exec: %w

Error message

db: RawSQL Exec: %w

What it means

Wraps an error from ExecContext in RawSQLRepository.Exec. Exec runs a statement that returns no rows; the driver rejected or failed to execute it. This is the standard failure point for malformed SQL, constraint violations, lock contention, or connectivity problems.

Source

Thrown at internal/storage/domain/db/raw_sql.go:58

			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)
	}
	affected, err := res.RowsAffected()
	if err != nil {
		return 0, fmt.Errorf("db: RawSQL Exec: rows affected: %w", err)
	}
	return affected, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped driver error — it names the exact SQL problem (syntax, missing table, constraint)
  2. Verify the statement against the current schema (tables/columns exist)
  3. Retry on lock-wait/deadlock errors; check for contending transactions
  4. If targeting wisp tables, ensure they exist in this deployment mode or route to the right table

Example fix

// before
n, err := repo.Exec(ctx, "DELET FROM issues WHERE id = ?", id) // syntax error
// after
n, err := repo.Exec(ctx, "DELETE FROM issues WHERE id = ?", id)
Defensive patterns

Strategy: validation

Validate before calling

// validate the statement against the schema before exec
var cnt int
_ = db.QueryRow("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ?", "issues").Scan(&cnt)
// cnt == 0 => table missing; abort before Exec

Type guard

func isExecError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "db: RawSQL Exec:") && !strings.Contains(err.Error(), "rows affected")
}

Try / catch

n, err := repo.Exec(ctx, stmt, args...)
if err != nil {
	var mysqlErr *mysqldriver.MySQLError
	if errors.As(err, &mysqlErr) && (mysqlErr.Number == 1213 || mysqlErr.Number == 1205) {
		// deadlock/lock-wait: retry
	}
	return err
}

Prevention

When it happens

Trigger: Calling RawSQLRepository.Exec with invalid SQL syntax, unknown table/column, constraint violation (dup key, FK), lock-wait timeout, or a dead connection.

Common situations: Hand-written migration/DML statements with typos; writing to a table that does not exist in the current schema version; deadlocks or lock waits under concurrency; referencing wisps tables that are absent in durable-only setups.

Related errors


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