{"record":{"id":"553387a57753e63a","repo":"golang-migrate/migrate","slug":"no-config-553387","errorCode":null,"errorMessage":"no config","messagePattern":"no config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"database/spanner/spanner.go","lineNumber":36,"sourceCode":"\n\t\"github.com/golang-migrate/migrate/v4\"\n\t\"github.com/golang-migrate/migrate/v4/database\"\n\n\tadminpb \"cloud.google.com/go/spanner/admin/database/apiv1/databasepb\"\n\t\"google.golang.org/api/iterator\"\n)\n\nfunc init() {\n\tdb := Spanner{}\n\tdatabase.Register(\"spanner\", &db)\n}\n\n// DefaultMigrationsTable is used if no custom table is specified\nconst DefaultMigrationsTable = \"SchemaMigrations\"\n\n// Driver errors\nvar (\n\tErrNilConfig      = errors.New(\"no config\")\n\tErrNoDatabaseName = errors.New(\"no database name\")\n\tErrNoSchema       = errors.New(\"no schema\")\n\tErrDatabaseDirty  = errors.New(\"database is dirty\")\n\tErrLockHeld       = errors.New(\"unable to obtain lock\")\n\tErrLockNotHeld    = errors.New(\"unable to release already released lock\")\n)\n\n// Config used for a Spanner instance\ntype Config struct {\n\tMigrationsTable string\n\tDatabaseName    string\n\t// Whether to parse the migration DDL with spansql before\n\t// running them towards Spanner.\n\t// Parsing outputs clean DDL statements such as reformatted\n\t// and void of comments.\n\tCleanStatements bool\n}\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/database/spanner/spanner.go#L18-L54","documentation":"spanner.ErrNilConfig is returned by the Spanner driver's WithInstance and WithConnection when the *Config argument is nil. The Spanner driver needs the Config (DatabaseName, schema, migrations table) to operate and fails fast rather than panicking on a nil dereference. Like the Cassandra variant, it indicates a caller bug.","triggerScenarios":"Calling database/spanner WithInstance(client, nil) or WithConnection(conn, nil); constructing the driver programmatically without populating the Config struct.","commonSituations":"Wiring the Spanner driver by hand instead of via a spanner:// URL, config structs left nil in tests, or refactorings that dropped config initialization.","solutions":["Pass a populated *spanner.Config (at minimum DatabaseName) to WithInstance/WithConnection.","Open via 'spanner://projects/P/instances/I/databases/D' so the library parses the config for you.","Nil-check the config in your wrapper code before invoking the driver."],"exampleFix":"// before\ndriver, err := spanner.WithInstance(client, nil)\n// after\ncfg := &spanner.Config{DatabaseName: \"projects/p/instances/i/databases/d\"}\ndriver, err := spanner.WithInstance(client, cfg)","handlingStrategy":"validation","validationCode":"if cfg == nil {\n    return fmt.Errorf(\"spanner driver requires a non-nil *spanner.Config\")\n}","typeGuard":"func hasSpannerConfig(cfg *spanner.Config) bool { return cfg != nil }","tryCatchPattern":"driver, err := spanner.WithInstance(client, cfg)\nif err != nil {\n    if errors.Is(err, spanner.ErrNilConfig) {\n        return fmt.Errorf(\"spanner driver setup: missing config: %w\", err)\n    }\n    return err\n}","preventionTips":["Build the Spanner Config in one place and pass it down explicitly.","Prefer migrate.New with a spanner:// URL to let the library parse config.","Cover driver construction with a test that asserts config is populated."],"tags":["go","configuration","spanner","go-migrate"],"backgroundTag":"missing-configuration","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}