googleapis/mcp-toolbox · error
failed to delete bucket %q: %w
Error message
failed to delete bucket %q: %w
What it means
DeleteBucket wraps any error from the GCS client's Bucket.Delete call with the bucket name. The library throws it because GCS only allows deleting empty buckets and requires delete permission; the underlying cause (not empty, 403, not found) is preserved via %w.
Source
Thrown at internal/sources/cloudstorage/cloudstorage.go:612
}
if err := s.client.Bucket(bucket).Object(object).Delete(ctx); err != nil {
return nil, fmt.Errorf("failed to delete object %q in bucket %q: %w", object, bucket, err)
}
return map[string]any{
"bucket": bucket,
"object": object,
"deleted": true,
}, nil
}
// DeleteBucket deletes an empty Cloud Storage bucket.
func (s *Source) DeleteBucket(ctx context.Context, bucket string) (map[string]any, error) {
if err := s.validateBucket(bucket); err != nil {
return nil, err
}
if err := s.client.Bucket(bucket).Delete(ctx); err != nil {
return nil, fmt.Errorf("failed to delete bucket %q: %w", bucket, err)
}
return map[string]any{
"bucket": bucket,
"deleted": true,
}, nil
}
func initGCSClient(ctx context.Context, tracer trace.Tracer, name, project string) (*storage.Client, error) {
//nolint:all // Reassigned ctx
ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceType, name)
defer span.End()
userAgent, err := util.UserAgentFromContext(ctx)
if err != nil {
return nil, err
}
View on GitHub (pinned to 8cc6e09de2)
Solutions
- Empty the bucket first: delete all objects (and object versions / soft-deleted copies, e.g. via gsutil rm -r or storage buckets objects list with versions)
- Check the wrapped cause: storage.ErrBucketNotExist vs 403 vs 'bucket not empty' to pick the fix
- Grant the service account roles/storage.admin or at minimum storage.buckets.delete
- Remove or expire any retention policy/lifecycle locks before deletion
- Retry transient 5xx errors with backoff
Example fix
// before
if err := emptyBucketObjects(ctx, src, bucket); err != nil { return err }
_, err := src.DeleteBucket(ctx, bucket)
// after
if err := emptyBucketObjects(ctx, src, bucket); err != nil { return err }
if err := purgeObjectVersionsAndSoftDeleted(ctx, src, bucket); err != nil { return err }
_, err := src.DeleteBucket(ctx, bucket) Defensive patterns
Strategy: validation
Validate before calling
// Before DeleteBucket, ensure bucket is empty (including versions/soft-deleted)
func bucketIsEmpty(ctx context.Context, src *cloudstorage.Source, bucket string) (bool, error) {
it, err := src.ListObjects(ctx, bucket, "")
if err != nil { return false, err }
return len(it) == 0, nil
} Try / catch
_, err := src.DeleteBucket(ctx, bucket)
if err != nil {
switch {
case strings.Contains(err.Error(), "not empty"):
// purge remaining objects/versions then retry
case strings.Contains(err.Error(), "403"):
// fix IAM
default:
return err
}
} Prevention
- Purge all object versions and soft-deleted objects before deleting a bucket
- Require storage.admin for bucket lifecycle operations
- Confirm the bucket has no retention policy or lock
- Never assume a bucket is empty just because the UI listing looks empty
When it happens
Trigger: Calling Source.DeleteBucket(ctx, bucket) when the bucket still contains objects (including object versions/soft-deleted objects), the caller lacks storage.buckets.delete permission, the bucket does not exist, the bucket name fails validateBucket, or a transient API error occurs.
Common situations: Trying to delete a bucket that appears empty but holds non-current object versions or soft-deleted objects, service account missing roles/storage.admin, deleting a bucket with retention policy or public access prevention conflicts, environment pointing at a region where the bucket doesn't exist.
Related errors
- failed to delete object %q in bucket %q: %w
- unable to create client: %w
- unable to create storage.NewClient for project %q: %w
- ErrReadSizeLimitExceeded
- ErrBinaryContent
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/2f0d632525429ab8.
Report an issue: GitHub.