{"record":{"id":"a1d3c868fb83942b","repo":"apache/beam","slug":"database-not-provided","errorCode":null,"errorMessage":"database not provided!","messagePattern":"database not provided!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"sdks/go/pkg/beam/io/spannerio/common.go","lineNumber":39,"sourceCode":"\t\"context\"\n\t\"fmt\"\n\n\t\"cloud.google.com/go/spanner\"\n\t\"google.golang.org/api/option\"\n\t\"google.golang.org/api/option/internaloption\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/credentials/insecure\"\n)\n\ntype spannerFn struct {\n\tDatabase     string          `json:\"database\"` // Database is the spanner connection string\n\tTestEndpoint string          // Optional endpoint override for local testing. Not required for production pipelines.\n\tclient       *spanner.Client // Spanner Client\n}\n\nfunc newSpannerFn(db string) spannerFn {\n\tif db == \"\" {\n\t\tpanic(\"database not provided!\")\n\t}\n\n\treturn spannerFn{\n\t\tDatabase: db,\n\t}\n}\n\nfunc (f *spannerFn) Setup(ctx context.Context) error {\n\tif f.client == nil {\n\t\tvar opts []option.ClientOption\n\n\t\t// Append emulator options assuming endpoint is local (for testing).\n\t\tif f.TestEndpoint != \"\" {\n\t\t\topts = []option.ClientOption{\n\t\t\t\toption.WithEndpoint(f.TestEndpoint),\n\t\t\t\toption.WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),\n\t\t\t\toption.WithoutAuthentication(),\n\t\t\t\tinternaloption.SkipDialSettingsValidation(),","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/spannerio/common.go#L21-L57","documentation":"spannerio's internal spannerFn constructor panics when the Cloud Spanner database string is empty. Every read/write function in the package builds on spannerFn, so an empty database path makes the pipeline impossible to configure. It is treated as a programmer error rather than a runtime failure.","triggerScenarios":"Calling newSpannerFn(\"\") indirectly via spannerio.Read/Query/Write (or newGeneratePartitionsFn/newQueryFn/newReadBatchFn/newWriteFn) with db == \"\".","commonSituations":"A config file or environment variable for the database is missing/empty; a flag default of \"\" never overridden; trimming a path like 'projects/p/instances/i/databases/d' incorrectly.","solutions":["Pass the full database path: projects/<proj>/instances/<inst>/databases/<db>.","Validate the db string is non-empty before calling spannerio.Read/Query/Write.","Check the config source (env var, flag) that supplies the database id."],"exampleFix":"// before\nspannerio.Read(s, cfg.DB, table, reflect.TypeOf(Row{})) // cfg.DB == \"\"\n// after\nif cfg.DB == \"\" {\n    return errors.New(\"spanner database is required\")\n}\nspannerio.Read(s, cfg.DB, table, reflect.TypeOf(Row{}))","handlingStrategy":"validation","validationCode":"if db == \"\" {\n    return errors.New(\"spanner database path is required\")\n}\nif !strings.HasPrefix(db, \"projects/\") {\n    return fmt.Errorf(\"expected fully qualified database path, got %q\", db)\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        if s, ok := r.(string); ok && s == \"database not provided!\" {\n            // handle\n        } else { panic(r) }\n    }\n}()","preventionTips":["Load the database from config with a required-field check at startup.","Use the full path projects/<proj>/instances/<inst>/databases/<db>.","Fail fast in flag/env parsing when the database is empty."],"tags":["go","apache-beam","spanner","panic","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}