golang-migrate/migrate · error
no config
Error message
no config
What it means
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.
Source
Thrown at database/spanner/spanner.go:36
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database"
adminpb "cloud.google.com/go/spanner/admin/database/apiv1/databasepb"
"google.golang.org/api/iterator"
)
func init() {
db := Spanner{}
database.Register("spanner", &db)
}
// DefaultMigrationsTable is used if no custom table is specified
const DefaultMigrationsTable = "SchemaMigrations"
// Driver errors
var (
ErrNilConfig = errors.New("no config")
ErrNoDatabaseName = errors.New("no database name")
ErrNoSchema = errors.New("no schema")
ErrDatabaseDirty = errors.New("database is dirty")
ErrLockHeld = errors.New("unable to obtain lock")
ErrLockNotHeld = errors.New("unable to release already released lock")
)
// Config used for a Spanner instance
type Config struct {
MigrationsTable string
DatabaseName string
// Whether to parse the migration DDL with spansql before
// running them towards Spanner.
// Parsing outputs clean DDL statements such as reformatted
// and void of comments.
CleanStatements bool
}
View on GitHub (pinned to 01a9643f14)
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.
Example fix
// before
driver, err := spanner.WithInstance(client, nil)
// after
cfg := &spanner.Config{DatabaseName: "projects/p/instances/i/databases/d"}
driver, err := spanner.WithInstance(client, cfg) Defensive patterns
Strategy: validation
Validate before calling
if cfg == nil {
return fmt.Errorf("spanner driver requires a non-nil *spanner.Config")
} Type guard
func hasSpannerConfig(cfg *spanner.Config) bool { return cfg != nil } Try / catch
driver, err := spanner.WithInstance(client, cfg)
if err != nil {
if errors.Is(err, spanner.ErrNilConfig) {
return fmt.Errorf("spanner driver setup: missing config: %w", err)
}
return err
} Prevention
- 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.
When it happens
Trigger: Calling database/spanner WithInstance(client, nil) or WithConnection(conn, nil); constructing the driver programmatically without populating the Config struct.
Common situations: Wiring the Spanner driver by hand instead of via a spanner:// URL, config structs left nil in tests, or refactorings that dropped config initialization.
Related errors
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/553387a57753e63a.
Report an issue: GitHub.