Paginate S3 prefix deletes#3214
Conversation
PR SummaryMedium Risk Overview Reviewed by Cursor Bugbot for commit 7624012. Bugbot is set up for automated code reviews on this repo. Configure here. |
❌ 2 Tests Failed:
View the top 2 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
There was a problem hiding this comment.
Code Review
This pull request refactors DeleteObjectsWithPrefix in the AWS storage implementation to use S3 pagination, preventing timeouts on large prefixes, and adds a safeguard to reject empty prefixes. A corresponding unit test was also added. The review feedback suggests two improvements: using aws.String for pointer conversion to maintain consistency with the AWS SDK, and simplifying the loop by removing the anonymous function used for scoping the context timeout.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
LGTM - correct use of the S3 paginator with per-page timeouts, plus a sensible empty-prefix guard.
Extended reasoning...
Overview
Small bug fix in packages/shared/pkg/storage/storage_aws.go (~40 LOC changed). DeleteObjectsWithPrefix previously invoked ListObjectsV2 once and deleted only the first page (max 1000 keys), silently leaving the rest. It now walks all pages via s3.NewListObjectsV2Paginator and delegates each page's DeleteObjects call to a new deleteObjects helper. An explicit guard rejects an empty prefix. A test asserts the empty-prefix guard.
Security risks
The empty-prefix guard is a defensive improvement — a bad caller can no longer accidentally enumerate/delete the entire bucket. No auth, crypto, or permission surface is touched. Nothing user-controllable reaches the S3 keys here.
Level of scrutiny
Low. This is a straightforward fix in a shared storage helper with an obvious real bug (1000-key ceiling) and a well-contained mitigation. Pagination is implemented with the SDK's own paginator (standard pattern), and each round-trip carries the same 5s timeout previously used for a single call. The deleted flag correctly preserves the pre-existing warn-on-empty behavior.
Other factors
- Per-page
context.WithTimeoutinside an IIFE-with-defer cancel()is the right shape to avoid leaking cancels across many pages. - Delete errors abort the walk mid-way, which is consistent with the previous behavior and appropriate for this call site.
- Test coverage for the paginator path itself is not added, but that requires mocking the S3 client and the added risk is low.
DeleteObjectsWithPrefix listed only the first ListObjectsV2 page (max 1000 keys), silently leaving any further objects undeleted; walk all pages, deleting each batch (<=1000 keys). Also reject an empty prefix, which would otherwise delete the whole bucket. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8cf67dc to
e6a25b4
Compare
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e6a25b4. Configure here.
DeleteObjectsWithPrefix only deleted the first ListObjectsV2 page (1000 keys max), so prefixes with more than 1000 objects left the rest behind. Now it pages through all of them. Also refuses an empty prefix so a bad call can't wipe the whole bucket.