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
- Use a valid column family name: letters, digits, underscores, hyphens, dots only (must match [_a-zA-Z0-9][-_.a-zA-Z0-9]*).
- If the table now exists, add the column family via an update path instead of re-creating the table; treat ALREADY_EXISTS as success.
- Grant roles/bigtable.admin so both create-table and create-family calls succeed.
- 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
- Restrict column family names to letters, digits, underscore, hyphen, dot.
- Remember the table is already created when this error fires — recover by adding the family, not recreating the table.
- Handle ALREADY_EXISTS on the family step as success for idempotency.
- Keep the admin client version current; create-table-then-family needs both permissions.
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
- failed to update cluster: %w
- failed to delete cluster: %w
- failed to get table: %w
- failed to create table: %w
- failed to delete table: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/b8ce8d05ff464854.
Report an issue: GitHub.