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

  1. Pass a populated *spanner.Config (at minimum DatabaseName) to WithInstance/WithConnection.
  2. Open via 'spanner://projects/P/instances/I/databases/D' so the library parses the config for you.
  3. 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

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.