golang-migrate/migrate · error
no schema
Error message
no schema
What it means
spanner.ErrNoSchema is returned by the Spanner driver's WithInstance, WithConnection, and Open when no schema name is configured. The driver uses the schema to qualify the migrations table; without it the DDL/DML it builds would be ambiguous. It signals missing or incomplete driver configuration.
Source
Thrown at database/spanner/spanner.go:38
"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
}
// Spanner implements database.Driver for Google Cloud Spanner
type Spanner struct {View on GitHub (pinned to 01a9643f14)
Solutions
- Include the schema in the connection string/URL so the driver can parse it.
- Populate the schema field in the *spanner.Config when constructing the driver manually.
- Validate the schema value (non-empty) before calling the driver.
Example fix
// before
cfg := &spanner.Config{DatabaseName: "projects/p/instances/i/databases/d"}
// after
cfg := &spanner.Config{DatabaseName: "projects/p/instances/i/databases/d", SchemaName: "public"} Defensive patterns
Strategy: validation
Validate before calling
if cfg == nil || cfg.SchemaName == "" {
return fmt.Errorf("spanner schema name is required to qualify the migrations table")
} Type guard
func hasSchema(cfg *spanner.Config) bool { return cfg != nil && cfg.SchemaName != "" } Try / catch
driver, err := spanner.WithInstance(client, cfg)
if errors.Is(err, spanner.ErrNoSchema) {
return fmt.Errorf("schema missing in spanner config or URL")
} Prevention
- Include the schema in every DSN template your tooling generates.
- Validate all config fields (database, schema, table) together before driver creation.
- When copying driver setups between databases, re-check schema-specific fields.
When it happens
Trigger: Open/WithInstance called without the schema component in the spanner URL or with an empty Config schema field; a DSN template that dropped the schema segment.
Common situations: Copying a DSN pattern from another driver (e.g. postgres) that did not include the schema part, env substitution leaving the schema blank, multi-schema setups where the schema config was accidentally removed.
Related errors
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/998f3f203f8b3ef9.
Report an issue: GitHub.