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

  1. Set DataSource.InstanceId to the Spanner instance name before opening.
  2. Use the full DSN form projects/<project>/instances/<instance>/databases/<database> so getDatabaseFromDSN-style parsing fills every part.
  3. 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

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


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/caa398afd7433ce6. Report an issue: GitHub.