apache/beam · critical
no database provided!
Error message
no database provided!
What it means
spannerio.Read panics when the database argument is an empty string. A table read always needs a fully qualified Cloud Spanner database path, and a missing one is treated as an immediate construction-time error before any query is built.
Source
Thrown at sdks/go/pkg/beam/io/spannerio/read.go:47
"google.golang.org/api/iterator"
)
// spannerTag is the struct tag key used to identify Spanner field names.
const (
spannerTag = "spanner"
)
func init() {
register.DoFn3x1[context.Context, []byte, func(beam.X), error]((*queryFn)(nil))
register.Emitter1[beam.X]()
}
// Read reads all rows from the given spanner table. It returns a PCollection<t> for a given type T.
// T must be a struct with exported fields that have the "spanner" tag. If the
// table has more rows than t, then Read is implicitly a projection.
func Read(s beam.Scope, db string, table string, t reflect.Type) beam.PCollection {
if db == "" {
panic("no database provided!")
}
cols := strings.Join(structx.InferFieldNames(t, spannerTag), ",")
return query(s, db, fmt.Sprintf("SELECT %v from %v", cols, table), t, newQueryOptions())
}
// Query executes a spanner query. It returns a PCollection<t> for a given type T. T must be a struct with exported
// fields that have the "spanner" tag. By default, the transform uses spanners partitioned read ability to split
// the results into bundles.
// If the underlying query is not root-partitionable you can disable batching via UseBatching.
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!")
}
View on GitHub (pinned to 12126d8942)
Solutions
- Pass the full path projects/<proj>/instances/<inst>/databases/<db>.
- Validate db != "" before calling spannerio.Read and fail with a clear error.
- Check the flag/env/config source that supplies the database identifier.
Example fix
// before
spannerio.Read(s, os.Getenv("DB"), "users", reflect.TypeOf(User{})) // env unset
// after
db := os.Getenv("DB")
if db == "" {
log.Fatal("spanner database must be set (projects/p/instances/i/databases/d)")
}
spannerio.Read(s, db, "users", reflect.TypeOf(User{})) Defensive patterns
Strategy: validation
Validate before calling
if db == "" {
return errors.New("spanner database path is required for spannerio.Read")
} Try / catch
defer func() {
if r := recover(); r != nil {
if s, ok := r.(string); ok && s == "no database provided!" {
// handle
} else { panic(r) }
}
}() Prevention
- Check env vars/flags for the database at pipeline startup.
- Use a single validated config struct for the Spanner coordinates.
- Reject empty database strings at flag-parse time with a clear message.
When it happens
Trigger: Calling spannerio.Read(s, "", table, t) — typically when the db comes from a flag/env/config that was never set.
Common situations: Unset SPANNER_DATABASE env var; empty flag default; config file missing the database key; code refactor dropping the parameter.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- database not provided!
- no database provided
- unable to create batch read only transaction:
- unable to partition query: %v
- spannerio.Query: invalid option: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ffdd1d2bcc3bfaeb.
Report an issue: GitHub.