{"record":{"id":"85756e478b314141","repo":"googleapis/mcp-toolbox","slug":"failed-to-update-cluster-w","errorCode":null,"errorMessage":"failed to update cluster: %w","messagePattern":"failed to update cluster: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/bigtable/admin_wrappers.go","lineNumber":118,"sourceCode":"\nfunc (s *Source) CreateCluster(ctx context.Context, instanceId, clusterId, zone string, numNodes int32) (any, error) {\n\tconf := &bigtable.ClusterConfig{\n\t\tInstanceID: instanceId,\n\t\tClusterID:  clusterId,\n\t\tZone:       zone,\n\t\tNumNodes:   numNodes,\n\t}\n\terr := s.InstanceAdmin.CreateCluster(ctx, conf)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create cluster: %w\", err)\n\t}\n\treturn map[string]string{\"status\": \"cluster created successfully\"}, nil\n}\n\nfunc (s *Source) UpdateCluster(ctx context.Context, instanceId, clusterId string, serveNodes int32) (any, error) {\n\terr := s.InstanceAdmin.UpdateCluster(ctx, instanceId, clusterId, serveNodes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to update cluster: %w\", err)\n\t}\n\treturn map[string]string{\"status\": \"cluster updated successfully\"}, nil\n}\n\nfunc (s *Source) DeleteCluster(ctx context.Context, instanceId, clusterId string) (any, error) {\n\terr := s.InstanceAdmin.DeleteCluster(ctx, instanceId, clusterId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to delete cluster: %w\", err)\n\t}\n\treturn map[string]string{\"status\": \"cluster deleted successfully\"}, nil\n}\n\nfunc (s *Source) GetTable(ctx context.Context, tableId string) (any, error) {\n\ttable, err := s.Admin.TableInfo(ctx, tableId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get table: %w\", err)\n\t}\n\treturn table, nil","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/bigtable/admin_wrappers.go#L100-L136","documentation":"This error wraps any failure returned by the Cloud Bigtable InstanceAdmin client's UpdateCluster call when the MCP tool invokes Source.UpdateCluster. The library wraps the underlying gRPC/API error with fmt.Errorf(\"failed to update cluster: %w\", err), so the original cause (permissions, not found, quota, invalid nodes) is preserved via the %w chain. Inspect the wrapped error with errors.Unwrap or %v to see the real gRPC status.","triggerScenarios":"Calling the bigtable update_cluster tool (Source.UpdateCluster in internal/sources/bigtable/admin_wrappers.go:118) where s.InstanceAdmin.UpdateCluster(ctx, instanceId, clusterId, serveNodes) returns a non-nil error: instance or cluster ID does not exist, caller lacks bigtable.clusters.update IAM permission, serveNodes value is invalid, or the gRPC call fails (timeout, network, quota).","commonSituations":"Typo in instanceId/clusterId (IDs are distinct from display names); service account missing Bigtable Admin role; autoscaling-enabled clusters rejecting manual serveNodes changes; transient gRPC Unavailable during zone maintenance; exceeding node quota in a region.","solutions":["Verify instanceId and clusterId exist (list instances/clusters via admin console or bigtable list tools) and use the ID, not the display name.","Check IAM: the caller's service account needs roles/bigtable.admin (or at least bigtable.clusters.update).","Inspect the wrapped error (gRPC status code) to distinguish NotFound vs PermissionDenied vs ResourceExhausted; fix the corresponding cause.","Retry transient failures (Unavailable/DeadlineExceeded) with backoff; check node quota if ResourceExhausted."],"exampleFix":"// before: blindly wrapping without surfacing the gRPC status\nreturn nil, fmt.Errorf(\"failed to update cluster: %w\", err)\n// after: caller-side discrimination of the wrapped error\nvar st *status.Status\nif errors.As(err, &st) && st.Code() == codes.NotFound {\n    log.Printf(\"cluster %s not found in instance %s\", clusterId, instanceId)\n}","handlingStrategy":"try-catch","validationCode":"// Go: verify inputs before calling UpdateCluster\nif instanceId == \"\" || clusterId == \"\" {\n    return fmt.Errorf(\"instanceId and clusterId are required\")\n}\nif serveNodes <= 0 {\n    return fmt.Errorf(\"serveNodes must be a positive integer\")\n}","typeGuard":"func isNotFound(err error) bool {\n    return status.Code(err) == codes.NotFound\n}","tryCatchPattern":"if err := src.UpdateCluster(ctx, inst, cluster, nodes); err != nil {\n    switch status.Code(err) {\n    case codes.NotFound:\n        // handle missing cluster\n    case codes.PermissionDenied:\n        // surface IAM guidance\n    case codes.Unavailable, codes.DeadlineExceeded:\n        // retry with backoff\n    default:\n        log.Printf(\"update cluster failed: %v\", err)\n    }\n}","preventionTips":["Use the exact cluster/instance IDs (not display names) from list operations.","Assign roles/bigtable.admin to the service account used by the tool.","Pre-validate serveNodes against cluster min/max and autoscaling settings.","Implement exponential-backoff retry for codes.Unavailable and DeadlineExceeded."],"tags":["gcp","bigtable","grpc","iam","admin-api"],"backgroundTag":"gcp-grpc-admin-operation-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}