bytebase/bytebase · error
instance ID cannot be empty
Error message
instance ID cannot be empty
What it means
Spanner driver Open validation: config.DataSource.InstanceId is empty. A Spanner connection must target one project/instance/database triple; without the instance the database name cannot be formed, so the driver refuses to open.
Source
Thrown at backend/plugin/db/spanner/spanner.go:71
client *spanner.Client
dbClient *spannerdb.DatabaseAdminClient
// databaseName is the currently connected database name.
databaseName string
}
func newDriver() db.Driver {
return &Driver{}
}
// Open opens a Spanner driver. It must connect to a specific database.
// If database isn't provided, part of the driver cannot function.
func (d *Driver) Open(ctx context.Context, _ storepb.Engine, config db.ConnectionConfig) (db.Driver, error) {
if config.DataSource.ProjectId == "" {
return nil, errors.New("project ID cannot be empty")
}
if config.DataSource.InstanceId == "" {
return nil, errors.New("instance ID cannot be empty")
}
d.config = config
d.connCtx = config.ConnectionContext
var o []option.ClientOption
if gcpCredential := config.DataSource.GetGcpCredential(); gcpCredential != nil {
credOption, err := util.GCPCredentialOption([]byte(gcpCredential.Content))
if err != nil {
return nil, err
}
o = append(o, credOption)
}
// host and port optionally override the default spanner.googleapis.com:443
// endpoint, e.g. with a Private Service Connect endpoint. gRPC defaults to
// port 443 when no port is given.
if host := config.DataSource.Host; host != "" {
endpoint := host
if port := config.DataSource.Port; port != "" {View on GitHub (pinned to 1870550677)
Solutions
- Set DataSource.InstanceId to the Spanner instance name before opening.
- Use the full DSN form projects/<project>/instances/<instance>/databases/<database> so getDatabaseFromDSN-style parsing fills every part.
- Verify the stored instance connection config in the metadata DB includes instance ID for Spanner engines.
Example fix
// before cfg.DataSource.ProjectId = "my-gcp-project" // after cfg.DataSource.ProjectId = "my-gcp-project" cfg.DataSource.InstanceId = "my-instance"
Defensive patterns
Strategy: validation
Validate before calling
if cfg.DataSource == nil || cfg.DataSource.InstanceId == "" {
return errors.New("spanner: InstanceId is required")
} Try / catch
driver, err := d.Open(ctx, engine, cfg)
if err != nil {
if strings.Contains(err.Error(), "instance ID cannot be empty") {
// prompt user to select a Spanner instance
}
} Prevention
- Require instance selection for Spanner connections in the UI.
- Re-derive InstanceId from the DSN when it is present there.
- Audit stored configs for Spanner engines missing instance ID.
When it happens
Trigger: Calling Open for engine SPANNER where config.DataSource.InstanceId is empty, even if ProjectId is set.
Common situations: A data source record that only stores project+database (project/project/databases/db DSN parsed without instance); a config hand-edited or synced from another engine; Spanner instance renamed/deleted so the field was cleared.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- project ID cannot be empty
- spanner: bad connection
- GCP credential JSON missing "type" field
- issuer_url is required for OIDC
- missing Azure Key Vault URL
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/caa398afd7433ce6.
Report an issue: GitHub.