Repository navigation
fix(core)!: keep literal request headers named after a method - #11156
Conversation
Request preparation deleted every `common` and method key from the merged headers, so a literal header whose name matches a supported method was dropped instead of being sent. `Link` is the notable case: it is a real request header, and header names are lowercased during config merge, so both `link` and `Link` were removed. Treat a `common` or method key as a structural default bucket only when it holds an object, and strip it in that case only. Literal values under those names now reach the adapter, while method-specific header defaults keep being removed as before.
|
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…eaders Any non-null object under a method name was treated as a defaults bucket, so a literal header holding a Date, Buffer or class instance was silently dropped. Restrict the check to plain objects and AxiosHeaders instances, which are the only shapes a defaults bucket can take.
|
Good catch on I did not take the suggested The check is now: const isHeadersBucket = (value) =>
value == null || utils.isPlainObject(value) || value instanceof AxiosHeaders;This covers both cases: Verified against all three variants with two added tests:
Full unit suite is green: 58 files, 1065 tests. |
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
The three header tests added by this change each declared an identical inline `echoHeaders` adapter. `tests/README.md` asks for reusable helpers to live in `tests/setup` rather than being copied between tests, so move it to `tests/setup/adapters.js` and import it. Test-only change; no production code is touched.
Recognize plain header maps and compatible AxiosHeaders across builds while allowing Date, Buffer, typed-array, and application class values to reach normal header serialization. BREAKING CHANGE: Custom class instances used as common or method defaults must be converted to plain maps or AxiosHeaders. Other non-plain objects are now literal header values.
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
View guided diff | Re-trigger cubic
Summary
Request preparation removes common and method-named defaults after flattening them. Since #11096 extended cleanup to every supported method, literal headers such as
Linkhave also been removed. Treating every object as a defaults bucket additionally drops Date, Buffer, typed-array, and application class values before normal header serialization.Limit defaults buckets to plain/null-prototype maps and compatible
AxiosHeaders, including subclasses and instances from another package build. Other values reach normal header serialization. Common defaults apply to every request; method defaults apply only to the matching method.Breaking compatibility change: custom class instances used as defaults buckets must be converted to a plain map or
AxiosHeaders. Otherwise they become literal header values, including on nonmatching requests.Linked issue
No separate issue. Fixes the literal-header regression introduced by #11096 and addresses the non-plain object finding, throwing brand-probe finding, and tag-only misclassification finding.
Changes
AxiosHeaders; require theAxiosHeaderssymbol brand and the core header-container interface for foreign instances (toJSON,set,get,has,delete,clear,normalize,concat,toString, and iteration). A tag andtoJSONalone do not classify an application object as a defaults bucket. Methods are checked for callability without invoking them, andgetSafePropexcludes shared-prototype values.Validation
Environment: macOS arm64, Node.js 24.18.0, npm 11.16.0. Base:
v1.xatf694ecd6. Latest fix:d2a6e81f.npm ci --ignore-scripts: passed in the root and both smoke fixtures.npm run test:vitest:unit -- tests/unit/axios.test.jsreproduced both new tagged-literal failures while the existing 37 tests passed. The final focused run, including own/inherited interface-getter failures, the serialization-error negative case, andtests/unit/syntaxCompat.test.js, passed 113 tests (41 Axios + 72 syntax checks). The earlier throwing-brand regression coverage remains intact.npm run lintandnpm run build: passed.npm run test:vitest:unit: 1,604 passed across 69 files.npm run test:vitest:browser:headless: 858 passed, 3 skipped across Chromium, Firefox, and WebKit. Installed Playwright browsers were available.npm pack --silent --pack-destination <temporary-directory>, thennpm install --no-save --ignore-scripts --package-lock=false <tarball>in each smoke fixture: passed.npm run test:smoke:esm:vitestintests/smoke/esm: 78 passed, including ESM/CJS constructor and subclass interoperability.npm run test:smoke:cjs:mochaintests/smoke/cjs: 72 passed, including defaults and subclasses from another packaged build.git diff --check: passed. Final diff inspected; no dependency, workflow, generated-artifact, version, debug, or focused-test changes.GitHub Actions for
d2a6e81f5d0a7c3b49ee08087214ff5a6977706erequire approval (action_required): Continuous integration, Bundle Size, zizmor, and build reproducibility. Their runtime/build results remain unverified on GitHub. The PR is conflict-free. Review bot results are separate from build/test evidence.Compatibility and documentation
Semver: major compatibility impact for arbitrary class defaults. Plain/null-prototype maps and compatible
AxiosHeadersretain defaults-bucket behavior. Other objects are literal header values. Applications using custom class instances as defaults maps must materialize their own enumerable header entries:Without migration, a custom
toString()may expose object contents in a literal header, including on nonmatching requests. This intentional restriction must be accounted for when scheduling the release; the overall PR is not a universally nonbreaking patch. Foreign header containers retain support through structural interface validation; tag-only application objects remain literal values. Failed optional probes fall back to normal serialization.No new APIs, options, exports, dependencies, or declaration changes. Object-to-string normalization is existing JavaScript behavior and does not expand TypeScript header-value declarations.
PRE_RELEASE_CHANGELOG.mddescribes the final behavior;PRE_RELEASE_DOCS.mdrecords deferred header/defaults guidance and migration. README and docs-site updates remain deferred to release preparation.Type/module declaration tests are not applicable because declarations and exports are unchanged; both runtime package formats were tested from the tarball. The full GitHub runtime matrix, including Bun and Deno, was not reproduced locally.
Checklist
PRE_RELEASE_CHANGELOG.mdentry added or updated