fix tasks bulk delete freezing app when selecting more than 500 tasks#7515
Conversation
The batch-delete endpoint capped requests at 500 IDs via Pydantic max_length, causing a 422 for larger selections. Flutter treated the non-200 as a failure and rolled back the optimistic deletion, freezing the UI with all tasks still visible. Removed the max_length cap from the request model and replaced the hard ValueError guard in the DB layer with chunked Firestore batch commits (500 ops per commit), matching the pattern already used by batch_update_action_items. Closes #7271 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Greptile SummaryThis PR fixes a UI freeze that occurred when bulk-deleting more than 500 tasks by replacing a hard 500-item Firestore batch limit with a chunked commit loop, and removing the corresponding Pydantic
Confidence Score: 4/5Safe to merge for the bulk-delete bug fix; the only open question is whether the completely unbounded request size is acceptable long-term. The chunking logic is straightforward and mirrors an existing pattern in the same file. The main concern is that removing max_length entirely leaves no guardrail against very large payloads, but this is a hardening question rather than a current breakage. A minor threshold inconsistency (500 vs 499) exists between the two batch functions but does not affect correctness. backend/routers/action_items.py — the removal of any upper bound on the IDs list deserves a second look. Important Files Changed
Sequence DiagramsequenceDiagram
participant Flutter
participant Router as POST /v1/action-items/batch-delete
participant DB as delete_action_items_batch
participant FS as Firestore
Flutter->>Router: "ids: [id1…idN] (N > 500)"
Router->>DB: delete_action_items_batch(uid, ids)
loop every 500 ids
DB->>FS: batch.commit() (up to 500 deletes)
FS-->>DB: OK
end
DB-->>Router: deleted_ids
Router->>Router: delete_action_item_vectors_batch
Router->>Router: send_action_items_batch_deletion_message
Router-->>Flutter: "{status: Ok, deleted_count: N}"
Reviews (1): Last reviewed commit: "fix(tasks): support bulk delete of more ..." | Re-trigger Greptile |
| batch.delete(action_items_ref.document(item_id)) | ||
| batch.commit() | ||
| count += 1 | ||
| if count >= 500: |
There was a problem hiding this comment.
Threshold inconsistency with sibling function
batch_update_action_items in the same file uses count >= 499 to stay safely under the 500-op Firestore limit (commits when 499 ops are queued), but this new code uses count >= 500. While committing a batch of exactly 500 ops is technically within the limit, the off-by-one inconsistency is surprising and could trip up a future reader who expects the two functions to match. Consider aligning both to >= 499 for consistency.
|
|
||
| class BatchDeleteActionItemsRequest(BaseModel): | ||
| ids: List[str] = Field(description="IDs of action items to delete", min_length=1, max_length=500) | ||
| ids: List[str] = Field(description="IDs of action items to delete", min_length=1) |
There was a problem hiding this comment.
No upper bound on request size
Removing max_length=500 leaves the endpoint with no cap on list size. A caller can now submit tens of thousands of IDs in a single request, which will loop through all of them on the main thread, block the worker for the full duration of N/500 sequential Firestore commits, and hold the entire payload in memory. Consider replacing the old 500-cap with a higher but still finite limit (e.g. max_length=10000) to prevent accidental or malicious overloads while still allowing bulk operations well beyond the old limit.
- Add max_length=10000 to BatchDeleteActionItemsRequest to prevent unbounded payloads while supporting any realistic task count - Align delete batch threshold to count >= 499 to match the sibling batch_update_action_items pattern in the same file Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
max_length=500fromBatchDeleteActionItemsRequest— Pydantic was rejecting requests with >500 IDs with a 422, causing Flutter to roll back the optimistic deletion and leaving the UI frozen with all tasks still visibleValueErrorguard indelete_action_items_batchwith chunked Firestore batch commits (500 ops per commit), matching the pattern already used bybatch_update_action_itemsin the same filesend_action_items_batch_deletion_message,delete_action_item_vectors_batch) already handles arbitrary list sizes — no changes needed thereTest plan
Closes #7271
🤖 Generated with Claude Code