Skip to content

fix: preserve symbol keys in merged request data#10812

Merged
jasonsaayman merged 12 commits into
axios:v1.xfrom
LaplaceYoung:fix/preserve-symbol-request-data
May 22, 2026
Merged

fix: preserve symbol keys in merged request data#10812
jasonsaayman merged 12 commits into
axios:v1.xfrom
LaplaceYoung:fix/preserve-symbol-request-data

Conversation

@LaplaceYoung
Copy link
Copy Markdown
Contributor

@LaplaceYoung LaplaceYoung commented Apr 28, 2026

Summary

  • Preserve enumerable symbol keys when Axios clones plain request data through utils.merge.
  • Use a length-guarded symbol loop and skip Buffer sources to match the existing forEach behavior.
  • Keep caseless matching limited to string keys so header merges keep their existing behavior.
  • Add regression coverage for enumerable symbols, non-enumerable symbols, caseless string matching with symbols, Buffer sources, and the request pipeline before transformRequest.

Verification

  • npx vitest run --project unit tests/unit/utils/merge.test.js tests/unit/api.test.js
  • npx eslint lib/utils.js
  • npx prettier --check tests/unit/utils/merge.test.js tests/unit/api.test.js
  • git diff origin/v1.x...HEAD --check

The final PR diff leaves the existing lib/utils.js formatting unchanged relative to v1.x.

npm run test:vitest:unit reached 583 passing tests out of 586. The three failures were existing network/DNS-dependent cases: postman-echo.com timeout, invalid-domain DNS timeout, and Node fetch reporting UND_ERR_SOCKET instead of ENOTFOUND.

Fixes #6392

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@jasonsaayman jasonsaayman added priority::medium A medium priority commit::fix The PR is related to a bugfix status::changes-requested A reviewer requested changes to the PR status::needs-rebase The PR requires a rebase labels Apr 30, 2026
Copy link
Copy Markdown
Member

@jasonsaayman jasonsaayman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch @LaplaceYoung. A couple of things to address before this can go in.

1. Avoid the per-request hot path allocation in lib/utils.js.

utils.merge runs on every request through mergeConfig, Axios.js:148, and lib/adapters/fetch.js:37. The new code allocates two arrays per source object (the getOwnPropertySymbols result and the .filter result) even when there are zero symbol keys, which is the common case for almost every config merge. Can you switch to a length-guarded indexed loop:

const symbols = Object.getOwnPropertySymbols(source);
for (let j = 0; j < symbols.length; j++) {
  const sym = symbols[j];
  if (Object.prototype.propertyIsEnumerable.call(source, sym)) {
    assignValue(source[sym], sym);
  }
}

That keeps the behavior but skips the .filter array entirely, and the loop body is dead when there are no symbols.

2. Drop the unrelated formatting changes.

The Prettier touch-ups in lib/utils.js:192-209 and 264-271 (semicolons on the arrow IIFEs, JSDoc whitespace, parens around the isFormData return) are not part of the fix. Please pull them out into a separate style: or chore: commit, or just revert them from this PR. Drive-by reformatting on a maintenance-line file makes git blame noisy and breaks the "failing test plus fix in separate commits" hygiene the PR template asks for.

Non-blocking nits, take or leave:

  • A test that confirms non-enumerable symbols are skipped would lock in the propertyIsEnumerable filter. Right now it is untested.
  • A caseless test mixing string and symbol keys (via merge.call({ caseless: true }, ...)) would also be nice to have, to pin the new typeof key === 'string' guard at line 413.
  • In the PR body, the three vitest failures you listed (postman-echo timeout, DNS timeout, UND_ERR_SOCKET) are pre-existing flakes. Worth saying so explicitly so the next reviewer does not re-investigate.

Let me know when the PR has been updated and I will take a look again

@Qodo-Free-For-OSS
Copy link
Copy Markdown

Hi, utils.merge skips Buffers in forEach, but the new symbol-merge pass still runs for Buffers, producing a partial/unexpected merge outcome for Buffer sources. This breaks the prior invariant that Buffer inputs contribute no merged keys and undermines the explicit Buffer skip logic.

Severity: informational | Category: correctness

How to fix: Skip symbols for Buffers

Agent prompt to fix - you can give this to your LLM of choice:

Issue description

utils.merge intentionally skips Buffers during key iteration (via forEach), but now still merges enumerable symbol keys from Buffer sources. This creates inconsistent/partial merge behavior for Buffers.

Issue Context

  • forEach returns early when isBuffer(obj).
  • merge now always runs a symbol enumeration step after forEach(source, assignValue).

Fix Focus Areas

  • lib/utils.js[406-441]

Suggested fix

Add a Buffer guard in merge’s loop (e.g., if (isBuffer(source)) continue;) or otherwise gate the symbol enumeration with the same logic used by forEach, so Buffer inputs are consistently ignored.


Found by Qodo code review

@LaplaceYoung
Copy link
Copy Markdown
Contributor Author

Thanks a lot for checking and reviewing my PR. I'm currently on the May Day holiday and didn't bring my work laptop with me, so I can't make timely edits to the PR right now.

@LaplaceYoung
Copy link
Copy Markdown
Contributor Author

Updated this PR for the review feedback:

  • Switched the symbol merge pass to a length-guarded indexed loop.
  • Dropped the unrelated lib/utils.js formatting changes from the final PR diff.
  • Added coverage for non-enumerable symbols and caseless string matching with symbol keys.
  • Added Buffer-source handling and regression coverage for the Qodo buffer-source report.
  • Updated the PR body with current verification and the existing flaky unit-test context.

Verification run:

  • npx vitest run --project unit tests/unit/utils/merge.test.js tests/unit/api.test.js
  • npx eslint lib/utils.js
  • npx prettier --check tests/unit/utils/merge.test.js tests/unit/api.test.js
  • git diff origin/v1.x...HEAD --check

@jasonsaayman ready for another look.

@LaplaceYoung
Copy link
Copy Markdown
Contributor Author

LaplaceYoung commented May 5, 2026

Updated again to resolve the GitHub conflict without merging the latest v1.x workflow commits into this fork branch.

What changed:

  • Kept the upstream own-property utils.merge guard compatible with the symbol-key fix.
  • Moved symbol-key handling ahead of the caseless string-key path so findKey continues to receive string keys only.
  • Confirmed local three-way merge against current origin/v1.x succeeds with git merge-tree --write-tree HEAD origin/v1.x.

Verification run:

  • npx vitest run --project unit tests/unit/utils/merge.test.js tests/unit/api.test.js tests/unit/prototypePollution.test.js
  • npx eslint lib/utils.js
  • git diff --check
  • git diff origin/v1.x...HEAD --check

Copy link
Copy Markdown
Member

@jasonsaayman jasonsaayman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🔥

@jasonsaayman jasonsaayman merged commit f70731b into axios:v1.x May 22, 2026
26 checks passed
@legowerewolf
Copy link
Copy Markdown

Woo! Thanks, guys.

jasonsaayman added a commit that referenced this pull request May 28, 2026
* fix: preserve symbol keys in merged request data

* fix: address symbol merge review feedback

* fix: align symbol merge with v1.x own-prop guard

* fix: avoid merge conflict on target key handling

* feat: collapsed the duplicated typeof key === symbol branch in assignValue

* chore: added should honor skipUndefined for symbol keys to lock in skipUndefined semantics

* chore: added should pass symbol keys to transformRequest through axios.create covering the instance

* fix(utils): skip symbol scan for arrays

---------

Co-authored-by: laplace young <[email protected]>
Co-authored-by: Jay <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit::fix The PR is related to a bugfix priority::medium A medium priority status::changes-requested A reviewer requested changes to the PR status::needs-rebase The PR requires a rebase

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Symbol keys are not preserved when data is being passed to transformRequest

4 participants