apache/beam · error

spannerio.Query: invalid option: %v

Error message

spannerio.Query: invalid option: %v

What it means

spannerio's newQueryOptions panics when any applied query option function returns an error, i.e. an invalid QueryOption was passed to spannerio.Read or spannerio.Query. Like natsio, options are validated eagerly at graph-construction time and bad ones are treated as programming errors.

Source

Thrown at sdks/go/pkg/beam/io/spannerio/query_options.go:45

// QueryOptionFn is a function that can be passed to Read or Query to configure options for reading or querying spanner.
type QueryOptionFn func(*queryOptions) error

// queryOptions represents additional options for executing a query.
type queryOptions struct {
	Batching       bool                   `json:"batching"`       // Batched reading, default is true.
	MaxPartitions  int64                  `json:"maxPartitions"`  // Maximum partitions
	TimestampBound spanner.TimestampBound `json:"timestampBound"` // The TimestampBound to use for batched reading
}

func newQueryOptions(options ...QueryOptionFn) queryOptions {
	opts := queryOptions{
		Batching: defaultBatching,
	}

	for _, opt := range options {
		if err := opt(&opts); err != nil {
			panic(fmt.Sprintf("spannerio.Query: invalid option: %v", err))
		}
	}

	return opts
}

// WithBatching sets whether we will use a batched reader. Batching is set to true by default, disable it when the
// underlying query is not root-partitionable.
func WithBatching(batching bool) QueryOptionFn {
	return func(opts *queryOptions) error {
		opts.Batching = batching
		return nil
	}
}

// WithMaxPartitions sets the maximum number of Partitions to split the query into when batched reading.
func WithMaxPartitions(maxPartitions int64) QueryOptionFn {
	return func(opts *queryOptions) error {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Check the wrapped error text in the panic to identify the offending option.
  2. Fix the option's values (e.g. positive batching limits) at the call site.
  3. Only use option constructors exported by the spannerio package.
  4. Pre-validate by calling opt(&opts) yourself and checking err before building the pipeline.

Example fix

// before
spannerio.Query(s, db, q, reflect.TypeOf(Row{}), spannerio.WithBatching(0, 0))
// after
spannerio.Query(s, db, q, reflect.TypeOf(Row{}), spannerio.WithBatching(10*1024*1024, 100))
Defensive patterns

Strategy: validation

Validate before calling

opts := queryOptions{Batching: defaultBatching}
for _, opt := range options {
    if err := opt(&opts); err != nil {
        return fmt.Errorf("invalid spannerio option: %w", err)
    }
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        if s, ok := r.(string); ok && strings.Contains(s, "spannerio.Query: invalid option") {
            // handle
        } else { panic(r) }
    }
}()

Prevention

When it happens

Trigger: Calling spannerio.Query/Read with an option that errors — e.g. invalid batching parameters (non-positive bytes/rows limits), or an option built for another connector.

Common situations: Setting Batching limits to zero or negative values; copying option helpers between spannerio and other io packages; editing an option constructor so it returns a validation error.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/6378116a144a947e. Report an issue: GitHub.