googleapis/mcp-toolbox · error

failed to create table: %w

Error message

failed to create table: %w

What it means

This error wraps failures from the Bigtable Admin client's CreateTable call in Source.CreateTable. The library wraps the underlying error with fmt.Errorf("failed to create table: %w", err) while keeping the original gRPC error chain intact. Note this fires before the optional column-family step; a bad columnFamily produces the separate 'failed to create column family' error instead.

Source

Thrown at internal/sources/bigtable/admin_wrappers.go:142

	err := s.InstanceAdmin.DeleteCluster(ctx, instanceId, clusterId)
	if err != nil {
		return nil, fmt.Errorf("failed to delete cluster: %w", err)
	}
	return map[string]string{"status": "cluster deleted successfully"}, nil
}

func (s *Source) GetTable(ctx context.Context, tableId string) (any, error) {
	table, err := s.Admin.TableInfo(ctx, tableId)
	if err != nil {
		return nil, fmt.Errorf("failed to get table: %w", err)
	}
	return table, nil
}

func (s *Source) CreateTable(ctx context.Context, tableId, columnFamily string) (any, error) {
	err := s.Admin.CreateTable(ctx, tableId)
	if err != nil {
		return nil, fmt.Errorf("failed to create table: %w", err)
	}
	if columnFamily != "" {
		if err := s.Admin.CreateColumnFamily(ctx, tableId, columnFamily); err != nil {
			return nil, fmt.Errorf("failed to create column family: %w", err)
		}
	}
	return map[string]string{"status": "table created successfully"}, nil
}

func (s *Source) DeleteTable(ctx context.Context, tableId string) (any, error) {
	err := s.Admin.DeleteTable(ctx, tableId)
	if err != nil {
		return nil, fmt.Errorf("failed to delete table: %w", err)
	}
	return map[string]string{"status": "table deleted successfully"}, nil
}

func (s *Source) ListTables(ctx context.Context) (any, error) {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Check if the table already exists (list_tables) and skip creation or use a new ID; handle gRPC ALREADY_EXISTS explicitly.
  2. Validate tableId against Bigtable naming rules before calling.
  3. Grant the caller roles/bigtable.admin (bigtable.tables.create).
  4. Retry transient gRPC errors with backoff; inspect status.Code(err) to pick the right branch.

Example fix

// before
err := s.Admin.CreateTable(ctx, tableId)
// after: tolerate idempotent re-runs
if code := status.Code(err); code != codes.AlreadyExists {
    return nil, fmt.Errorf("failed to create table: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Go: pre-flight checks before CreateTable
if !regexp.MustCompile(`^[_a-zA-Z0-9][-_.a-zA-Z0-9]*$`).MatchString(tableId) {
    return fmt.Errorf("invalid table id: %q", tableId)
}
existing, _ := admin.Tables(ctx)
for _, t := range existing {
    if t == tableId {
        return nil // already created; skip
    }
}

Type guard

func isAlreadyExists(err error) bool {
    return status.Code(err) == codes.AlreadyExists
}

Try / catch

if err := src.CreateTable(ctx, tableId, cf); err != nil {
    if status.Code(err) == codes.AlreadyExists {
        return nil // idempotent re-run
    }
    return fmt.Errorf("create table: %w", err)
}

Prevention

When it happens

Trigger: Calling the bigtable create_table tool where s.Admin.CreateTable(ctx, tableId) errors: the table already exists (ALREADY_EXISTS), invalid table ID characters, missing bigtable.tables.create permission, or a transient gRPC failure.

Common situations: Re-running a script that already created the table; invalid IDs (Bigtable IDs must match [_a-zA-Z0-9][-_.a-zA-Z0-9]*); service account lacking Bigtable Admin; emulator not running during local dev.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/ed9409be6202908b. Report an issue: GitHub.