Repository navigation
fix(claude): expire idle picker uploads while preserving backpressure - #7784
Conversation
Publish the exact locally tested candidate tree. See the draft PR for focused validation, remaining native/operational coverage and acceptance holds.
Preserve the published PR history while integrating dev 9e48f78. Retain the idle-only policy, request backpressure handling and response cleanup. Validation: Bun 1.4.4, 83 focused TLS tests; typecheck, structure, privacy, file-size gates and 593-page documentation build passed.
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Idle guard and transport cleanup src/claude/intercept/picker-listener.ts, structure/clients/claude-desktop.md, docs-site/src/content/docs/.../guides/claude-code.md |
The relay adds a configurable idle timeout with a 60-second default. Upload progress resets the timer; upstream backpressure pauses it. Upload completion or the first upstream response clears it. On timeout, the unfinished upload stops without a success response. Cleanup aborts the HTTP/1.1 socket before a complete reply and cancels only the affected HTTP/2 stream. The client structure note and localized guides document the behavior and its limits. |
Timeout and backpressure tests tests/helpers/picker-upload-backpressure.ts, tests/claude-integration/claude-picker-upload.test.ts |
The tests cover idle uploads, continuing progress, completed uploads, long-lived responses, and backpressure over HTTP/1 and HTTP/2. The helper observes backpressure, resumes delivery, checks payload bytes, and restores the original pipe method. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix
Sequence Diagram(s)
sequenceDiagram
participant Client
participant PickerListener
participant Upstream
Client->>PickerListener: Send upload body
PickerListener->>Upstream: Relay body
Upstream-->>PickerListener: Apply backpressure
PickerListener->>PickerListener: Pause idle timer
Upstream-->>PickerListener: Return first response
PickerListener->>PickerListener: Clear idle timer
Suggested labels: review-ready
Suggested reviewers: lidge-jun, ingwannu
Merge Risk: 
Minimal · up to f52b8
-
No merge-blocking issue is established. Installed-client and live-edge behavior remain unverified.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passedFull details: Docstring Coverage
-
Explanation
Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 3 files. (9 skipped: 9 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands.
|
✅ Deterministic PR hygiene checks passed. |
|
Maintainer integration into
|
Summary
Expire unfinished Picker uploads after 60 seconds without body progress, before the first upstream response. Nonempty chunks reset the idle timer, and upstream backpressure pauses it. Completion, response, cancellation and shutdown remove the guard. There is no absolute upload-duration limit, so a slow upload can continue while it makes progress.
HTTP/1.1 expiry closes the underlying socket without an empty success response. HTTP/2 expiry resets only the affected stream with
NGHTTP2_CANCEL. The admission slot is released, while sibling streams and existing response cleanup are preserved. Eight localized guides document the behavior.This replaces the absolute-deadline approach discussed in #7015 with an idle-only proposal. It does not claim an observed live claude.ai incident or a production-verified fix. Whether an additional local bound is useful when the edge normally enforces its own timeout, and whether 60 seconds is the right default, remain review questions.
Verification
Implementation validation at
f52b83be, using Bun 1.4.4 on Linux:f52b83beb7a66ddc68f6f1db118d6101230f6e16, attempt 1: 11 successful jobs / 10 policy skips / 0 failures. Catalog async contracts and the latest target/hygiene/label checks also passed. This upstream run used fast import-graph selection (test changed); the four-shard Ubuntu matrix, desktop shell and native macOS/Windows jobs were policy-skipped. Earlier same-commit four-shard validation remains separate historical evidence.Readiness scope
The unchanged head is conflict-free and five commits behind inspected
dev@736fa5087c0b807cc2c7fd54ebae1548e6b2d4cb. The recorded CI checkoutee4eacf828a77847ba9a7e4418951f33f51135b9combined this head with then-currentdev@2606f6f9; it is not a new run on the later dev commit. There are no unresolved upstream inline findings. CodeRabbit skipped the Draft, so this update does not claim completed upstream automated review.Ready for review of the disclosed idle-only proposal. Live-edge reproduction, whether an additional local bound is useful, and the 60-second default remain open review questions. No code, timeout or live setting changed for this readiness update, and passing checks were not repeated.
Checklist
Summary by CodeRabbit