apache/beam · error
spannerio.Query: specifying timestamp bound for non-batched…
Error message
spannerio.Query: specifying timestamp bound for non-batched reads not currently supported.
What it means
The internal query() path (non-batched reads) panics if queryOptions.TimestampBound was set, because stale-read bounds are only implemented for the batched read path. It is an explicit unsupported-feature guard in spannerio.
Solutions
- Enable batching with spannerio.UseBatching(true) as a QueryOptionFn so the timestamp bound is honored via readBatch.
- Remove the timestamp bound option if strong/regular reads are acceptable.
- Implement a custom DoFn with the Spanner client directly if neither option fits.
Example fix
// before spannerio.Query(s, db, q, t, spannerio.WithQueryTimestampBound(tb)) // after spannerio.Query(s, db, q, t, spannerio.UseBatching(true), spannerio.WithQueryTimestampBound(tb))
Defensive patterns
Strategy: validation
Validate before calling
if timestampBound != (spanner.TimestampBound{}) && !batchingEnabled {
return fmt.Errorf("timestamp bound requires spannerio.UseBatching(true)")
} Try / catch
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("spannerio timestamp bound unsupported here: %v", r)
}
}() Prevention
- Only set WithQueryTimestampBound together with UseBatching(true).
- Read the spannerio package docs on batching before adding staleness reads.
- Add an integration test for any pipeline using timestamp bounds.
When it happens
Trigger: Calling spannerio.Query (or Read) with WithQueryTimestampBound(spanner.StrongRead()) or any TimestampBound while batching is disabled (default, or UseBatching(false)).
Common situations: Users copying batched-read examples and adding timestamp bounds, or enabling staleness reads for consistency tuning without realizing it requires the batching path.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/58bf8c89c1bee7f3.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/io/spannerio/read.go:77
func Query(s beam.Scope, db string, q string, t reflect.Type, options ...QueryOptionFn) beam.PCollection {
queryOptions := newQueryOptions(options...)
if db == "" {
panic("no database provided!")
}
if queryOptions.Batching {
return readBatch(s, db, q, t, queryOptions)
} else {
return query(s, db, q, t, queryOptions)
}
}
func query(s beam.Scope, db string, query string, t reflect.Type, options queryOptions) beam.PCollection {
s = s.Scope("spanner.Query")
if options.TimestampBound != (spanner.TimestampBound{}) {
panic("spannerio.Query: specifying timestamp bound for non-batched reads not currently supported.")
}
imp := beam.Impulse(s)
return beam.ParDo(s, newQueryFn(db, query, t, options), imp, beam.TypeDefinition{Var: beam.XType, T: t})
}
type queryFn struct {
spannerFn
Query string `json:"query"` // Table is the table identifier.
Type beam.EncodedType `json:"type"` // Type is the encoded schema type.
Options queryOptions `json:"options"` // Options specifies additional query execution options.
}
func newQueryFn(
db string,
query string,
t reflect.Type,View on GitHub (pinned to 12126d8942)