{"record":{"id":"d984a28f5f3dad82","repo":"googleapis/mcp-toolbox","slug":"failed-to-delete-object-q-in-bucket-q-w","errorCode":null,"errorMessage":"failed to delete object %q in bucket %q: %w","messagePattern":"failed to delete object %q in bucket %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/cloudstorage/cloudstorage.go","lineNumber":596,"sourceCode":"\t\treturn nil, fmt.Errorf(\"failed to move %q to %q in bucket %q: %w\", sourceObject, destinationObject, bucket, err)\n\t}\n\n\treturn map[string]any{\n\t\t\"bucket\":            bucket,\n\t\t\"sourceObject\":      sourceObject,\n\t\t\"destinationObject\": destinationObject,\n\t\t\"bytes\":             attrs.Size,\n\t\t\"contentType\":       attrs.ContentType,\n\t}, nil\n}\n\n// DeleteObject deletes a GCS object.\nfunc (s *Source) DeleteObject(ctx context.Context, bucket, object string) (map[string]any, error) {\n\tif err := s.validateBucket(bucket); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := s.client.Bucket(bucket).Object(object).Delete(ctx); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to delete object %q in bucket %q: %w\", object, bucket, err)\n\t}\n\n\treturn map[string]any{\n\t\t\"bucket\":  bucket,\n\t\t\"object\":  object,\n\t\t\"deleted\": true,\n\t}, nil\n}\n\n// DeleteBucket deletes an empty Cloud Storage bucket.\nfunc (s *Source) DeleteBucket(ctx context.Context, bucket string) (map[string]any, error) {\n\tif err := s.validateBucket(bucket); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := s.client.Bucket(bucket).Delete(ctx); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to delete bucket %q: %w\", bucket, err)\n\t}\n","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/cloudstorage/cloudstorage.go#L578-L614","documentation":"DeleteObject wraps any error returned by the GCS client's Object.Delete call with the object and bucket names. The library throws it whenever the underlying Cloud Storage API rejects or fails the delete operation; the wrapped cause (e.g. storage.ErrObjectNotExist, 403, preconditions) is preserved via %w.","triggerScenarios":"Calling Source.DeleteObject(ctx, bucket, object) when the object does not exist, the caller lacks storage.objects.delete permission, a generation precondition fails (object was modified concurrently), the bucket name fails validateBucket, or a transient GCS/network error occurs.","commonSituations":"Deleting an already-removed object (double delete in cleanup jobs), service account missing storage.admin or objectAdmin role, deleting objects with retention/hold policies applied, typos in object names, or bucket configured with retention lock.","solutions":["Check the wrapped cause: errors.Is(err, storage.ErrObjectNotExist) means the object is already gone — treat as success for idempotent cleanup","Verify the credentials/service account has roles/storage.objectAdmin (or storage.objects.delete) on the bucket","Confirm the object name exactly matches (no leading slash, correct encoding)","Check for retention policy, event-based hold, or temporary hold on the object/bucket and lift them before deleting","Retry on transient errors (5xx, context deadline) with backoff"],"exampleFix":"// before\n_, err := src.DeleteObject(ctx, bucket, object)\nif err != nil { return err }\n// after\n_, err := src.DeleteObject(ctx, bucket, object)\nif err != nil {\n    if errors.Is(err, storage.ErrObjectNotExist) {\n        return nil // already deleted, idempotent\n    }\n    return fmt.Errorf(\"delete %s/%s: %w\", bucket, object, err)\n}","handlingStrategy":"try-catch","validationCode":"if bucket == \"\" || object == \"\" { return errors.New(\"bucket and object are required\") }","typeGuard":null,"tryCatchPattern":"res, err := src.DeleteObject(ctx, bucket, object)\nif err != nil {\n    if strings.Contains(err.Error(), \"notExist\") || errors.Is(err, storage.ErrObjectNotExist) {\n        // treat as already deleted\n        return nil\n    }\n    if strings.Contains(err.Error(), \"403\") {\n        // permissions problem: check IAM roles\n    }\n    return err\n}","preventionTips":["Make delete calls idempotent by tolerating ErrObjectNotExist","Grant the service account storage.objectAdmin on the bucket","Verify object names with a List/Get before delete in critical flows","Check retention/hold policies before scheduling deletes"],"tags":["gcs","cloud-storage","delete","wrap-error"],"backgroundTag":"gcs-object-delete-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"}