googleapis/mcp-toolbox · error

failed to create column family: %w

Error message

failed to create column family: %w

What it means

This error wraps failures from the Bigtable Admin client's CreateColumnFamily call inside Source.CreateTable, raised only when a non-empty columnFamily argument is supplied. The library wraps the underlying error with fmt.Errorf("failed to create column family: %w", err); the table itself was already created successfully at this point. The original gRPC cause is preserved in the chain.

Source

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

	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) {
	tables, err := s.Admin.Tables(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to list tables: %w", err)
	}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Use a valid column family name: letters, digits, underscores, hyphens, dots only (must match [_a-zA-Z0-9][-_.a-zA-Z0-9]*).
  2. If the table now exists, add the column family via an update path instead of re-creating the table; treat ALREADY_EXISTS as success.
  3. Grant roles/bigtable.admin so both create-table and create-family calls succeed.
  4. Retry only the column family step on transient gRPC errors to avoid duplicating table creation.

Example fix

// before: one-shot call that leaves a half-created table on family failure
err := s.Admin.CreateTable(ctx, tableId)
// after: make the family step idempotent
if err := s.Admin.CreateColumnFamily(ctx, tableId, cf); err != nil && status.Code(err) != codes.AlreadyExists {
    return nil, fmt.Errorf("failed to create column family: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate column family name before CreateTable
var cfRe = regexp.MustCompile(`^[_a-zA-Z0-9][-_.a-zA-Z0-9]*$`)
if columnFamily != "" && !cfRe.MatchString(columnFamily) {
    return fmt.Errorf("invalid column family name: %q", columnFamily)
}

Type guard

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

Try / catch

if err := src.CreateTable(ctx, tableId, cf); err != nil {
    if strings.Contains(err.Error(), "failed to create column family") &&
        status.Code(errors.Unwrap(err)) == codes.AlreadyExists {
        return nil // family already present
    }
    return fmt.Errorf("create table: %w", err)
}

Prevention

When it happens

Trigger: Calling the bigtable create_table tool with a columnFamily argument where s.Admin.CreateColumnFamily(ctx, tableId, columnFamily) errors: column family name contains invalid characters, the family already exists, permissions missing (bigtable.tables.update), or transient gRPC failure after the table was created.

Common situations: Using names with spaces or invalid characters for the family; re-running creation after the family already exists; partial-failure states where the table exists but the family step failed; IAM gaps on the service account.

Related errors


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