Skip to content

fix(retry): make RetryController rawHeaders/rawTrailers writable - #5766

Closed
pacocartones wants to merge 1 commit into
nodejs:mainfrom
pacocartones:fix/5726-retry-rawheaders
Closed

fix(retry): make RetryController rawHeaders/rawTrailers writable#5766
pacocartones wants to merge 1 commit into
nodejs:mainfrom
pacocartones:fix/5726-retry-rawheaders

Conversation

@pacocartones

Copy link
Copy Markdown
Contributor

Fixes #5726.

Problem

RetryController (lib/handler/retry-handler.js) exposed rawHeaders and rawTrailers as getter-only accessors, but the real RequestController (lib/core/request.js) declares them as writable data properties. Interceptors composed downstream of retry legitimately reassign them — the decompress interceptor does controller.rawHeaders = filteredHeaders (to strip content-encoding/content-length), and the cache interceptor does the same. When retry sits ahead of decompress, the interceptor gets the retry proxy and the assignment throws:

TypeError: Cannot set property rawHeaders of #<RetryController> which has only a getter

rawTrailers had the identical latent defect (assigned by request.js and mock-utils.js).

Fix

Add forwarding setters to the proxy, mirroring the existing getters and the writable fields of the real controller — making the proxy transparent for writes as it already is for reads. Consistent with the proxy's design ("always forwards to the controller of the currently active connection").

Test

  • test/retry-handler-controller-proxy.js — unit: forwards rawHeaders/rawTrailers writes (RED: getter-only TypeError; GREEN: forwarded).
  • test/interceptors/decompress.js — end-to-end: retry composed before decompress (RED at HEAD; GREEN with fix).

decompress 28/28, retry-handler/retry-agent suites, npm run lint — all green.

…roxy

The RetryController proxy handed to downstream handlers exposed rawHeaders
and rawTrailers as getter-only accessors. Interceptors composed after retry
(decompress, cache) reassign controller.rawHeaders to strip headers they have
consumed, so the assignment threw "Cannot set property rawHeaders of
RetryController which has only a getter" and the request failed with a
TypeError. Add setters that forward the write to the active connection's
controller, matching the transparent-proxy contract and the writable
rawHeaders/rawTrailers of RequestController.

Fixes: nodejs#5726
@codecov-commenter

codecov-commenter commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.50%. Comparing base (17117f6) to head (14f8c3d).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5766      +/-   ##
==========================================
- Coverage   93.50%   93.50%   -0.01%     
==========================================
  Files         110      110              
  Lines       39072    39074       +2     
==========================================
+ Hits        36534    36535       +1     
- Misses       2538     2539       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mcollina

mcollina commented Sep 4, 2026

Copy link
Copy Markdown
Member

Sorry, can you rebase?

@pacocartones

Copy link
Copy Markdown
Contributor Author

Closing this — it turned out to duplicate #5727 (by @official-burak), which landed the same rawHeaders/rawTrailers setters on RetryController plus equivalent regression tests, and has already merged into main. So there's nothing left for this PR to add and no rebase is needed. Thanks @mcollina for taking a look! 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

retry + decompress: RetryController exposes read-only rawHeaders, causing TypeError

3 participants