Skip to content

Clean up error handling, fix a proto-pollution gap, and seal a few loose ends#10922

Merged
jasonsaayman merged 7 commits into
axios:v1.xfrom
Mohammad-Faiz-Cloud-Engineer:v1.x
May 26, 2026
Merged

Clean up error handling, fix a proto-pollution gap, and seal a few loose ends#10922
jasonsaayman merged 7 commits into
axios:v1.xfrom
Mohammad-Faiz-Cloud-Engineer:v1.x

Conversation

@Mohammad-Faiz-Cloud-Engineer

@Mohammad-Faiz-Cloud-Engineer Mohammad-Faiz-Cloud-Engineer commented May 20, 2026

Copy link
Copy Markdown
Contributor

Been poking around the codebase and found a handful of things that needed tidying up:

  • resolveConfig.js - config.params and config.paramsSerializer were being accessed directly off user input instead of going through the own() guard. If someone crafted a config with inherited params from the prototype, you'd get unexpected behavior. Swapped to own('params') / own('paramsSerializer') like the rest of the module does.

  • http.js - there was a stray console.warn('emit error', err) in an abort-event catch block. Debug leftover, shouldn't reach production. Replaced with a quiet catch.

  • AxiosHeaders.js - three places were throwing raw Error or TypeError instead of AxiosError. Swapped them over with ERR_BAD_OPTION_VALUE. Also added the missing AxiosError import (creates a circular dep with AxiosError.js which imports AxiosHeaders, but it works fine at runtime since the throws are inside method bodies, not at module eval time).

  • toFormData.js - the circular reference detection was throwing a bare Error. Changed to AxiosError without a code, so it stays distinguishable from the depth-exceeded error that uses ERR_FORM_DATA_DEPTH_EXCEEDED. (There's a test that explicitly checks this distinction.)

  • formDataToStream.js - two more raw throws (TypeError and Error) → AxiosError.

  • buildURL.js - import self-path ../helpers/AxiosURLSearchParams.js when it lives in the same directory as the importer. Changed to ./AxiosURLSearchParams.js.

  • index.d.cts - CanceledError was missing readonly name: 'CanceledError' that index.d.ts already has. Added it to keep the CJS declarations in sync.

Lint passes clean, all 770 unit tests green. Nothing breaking - all changes are either internal (no consumer-facing API change) or type-only.


Summary by cubic

Hardened config resolution to block prototype pollution in params/paramsSerializer, kept native error types, and tidied a few minor issues. Also updated pre-release notes.

Description

  • Guard resolveConfig with own('params') and own('paramsSerializer') to ignore inherited values.
  • Keep native Error/TypeError in AxiosHeaders, formDataToStream, and toFormData (use new where missing).
  • Fix buildURL import to ./AxiosURLSearchParams.js; silence stray console.warn in the Node HTTP abort handler.
  • Add readonly name: 'CanceledError' to CJS typings in index.d.cts.

Docs

  • Added pre-release changelog notes for config hardening and CJS CanceledError typing.
  • Suggest adding a short note in /docs/ that config resolution ignores inherited params/paramsSerializer.

Testing

  • Added unit tests to ensure resolveConfig ignores inherited params and paramsSerializer and does not call polluted serializers.
  • No additional tests needed.

Semantic version impact

  • Patch. No API changes.

Written for commit d537120. Summary will update on new commits. Review in cubic

…ose ends.

Been poking around the codebase and found a handful of things that needed tidying up:

- resolveConfig.js - config.params and config.paramsSerializer were being accessed directly off user input instead of going through the own() guard. If someone crafted a config with inherited params from the prototype, you'd get unexpected behavior. Swapped to own('params') / own('paramsSerializer') like the rest of the module does.

- http.js - there was a stray console.warn('emit error', err) in an abort-event catch block. Debug leftover, shouldn't reach production. Replaced with a quiet catch.

- AxiosHeaders.js - three places were throwing raw Error or TypeError instead of AxiosError. Swapped them over with ERR_BAD_OPTION_VALUE. Also added the missing AxiosError import (creates a circular dep with AxiosError.js which imports AxiosHeaders, but it works fine at runtime since the throws are inside method bodies, not at module eval time).

- toFormData.js - the circular reference detection was throwing a bare Error. Changed to AxiosError without a code, so it stays distinguishable from the depth-exceeded error that uses ERR_FORM_DATA_DEPTH_EXCEEDED. (There's a test that explicitly checks this distinction.)

- formDataToStream.js - two more raw throws (TypeError and Error) → AxiosError.

- buildURL.js - import self-path ../helpers/AxiosURLSearchParams.js when it lives in the same directory as the importer. Changed to ./AxiosURLSearchParams.js.

- index.d.cts - CanceledError was missing readonly name: 'CanceledError' that index.d.ts already has. Added it to keep the CJS declarations in sync.

Lint passes clean, all 770 unit tests green. Nothing breaking - all changes are either internal (no consumer-facing API change) or type-only.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 7 files

Confidence score: 5/5

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

Re-trigger cubic

@jasonsaayman jasonsaayman added priority::medium A medium priority commit::refactor The PR is related to refactoring labels May 24, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread lib/core/AxiosHeaders.js Outdated

@jasonsaayman jasonsaayman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this could land as it is. We would have a couple of breaking changes.

Comment thread lib/core/AxiosHeaders.js Outdated
Comment thread lib/core/AxiosHeaders.js
Comment thread lib/core/AxiosHeaders.js
Comment thread lib/helpers/formDataToStream.js
Comment thread lib/helpers/formDataToStream.js
Comment thread lib/helpers/toFormData.js
Comment thread lib/helpers/resolveConfig.js
@jasonsaayman jasonsaayman added the status::changes-requested A reviewer requested changes to the PR label May 26, 2026
Reverts AxiosError throws back to native Error/TypeError in AxiosHeaders,
formDataToStream, and toFormData to avoid breaking existing consumers
who catch by constructor name or check isAxiosError().

Adds regression tests for resolveConfig own('params')/own('paramsSerializer')
guard as requested in review.

Removes unused AxiosError imports from AxiosHeaders and formDataToStream.
@Mohammad-Faiz-Cloud-Engineer

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @jasonsaayman. I've addressed all the feedback:

Reverted - all 6 error-type changes that were breaking:

  • AxiosHeaders.js: 3 throws back to native Error/TypeError (the set() empty header name, set() iterator type, and get() parser validator)

  • formDataToStream.js: 2 throws back to native TypeError/Error

  • toFormData.js: circular reference throw back to native Error

Removed the unused AxiosError imports that the PR had added alongside those throws.

Added - 2 regression tests in prototypePollution.test.js for the resolveConfig own('params') / own('paramsSerializer') guard, verifying that polluted prototype values are correctly ignored.

Kept the non-breaking fixes (buildURL import path, http.js quiet catch, index.d.cts CanceledError name sync).
Lint passes clean, all 732 unit tests green.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

3 issues found across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread lib/core/AxiosHeaders.js
Comment thread lib/helpers/formDataToStream.js
Comment thread lib/helpers/toFormData.js
@Mohammad-Faiz-Cloud-Engineer

Copy link
Copy Markdown
Contributor Author

The three files flagged in the description as switching to AxiosError (AxiosHeaders.js, formDataToStream.js, toFormData.js) were reverted back to native Error/TypeError per maintainer review those are non-breaking now. The AxiosError imports were removed too.

What was actually changed in f3a9873:

  • resolveConfig.js --> own() guard on params/paramsSerializer (proto-pollution fix) + 2 regression tests
  • buildURL.js --> self-path import fix
  • http.js --> quiet catch on abort (removed console.warn)
  • index.d.cts --> add missing CanceledError readonly name

All 732 unit tests pass, lint clean. No breaking changes.

@jasonsaayman jasonsaayman removed the status::changes-requested A reviewer requested changes to the PR label May 26, 2026
@jasonsaayman jasonsaayman merged commit 73a7c55 into axios:v1.x May 26, 2026
26 checks passed
jasonsaayman added a commit that referenced this pull request May 28, 2026
…ew loose ends (#10922)

* Clean up error handling, fix a proto-pollution gap, and seal a few loose ends.

Been poking around the codebase and found a handful of things that needed tidying up:

- resolveConfig.js - config.params and config.paramsSerializer were being accessed directly off user input instead of going through the own() guard. If someone crafted a config with inherited params from the prototype, you'd get unexpected behavior. Swapped to own('params') / own('paramsSerializer') like the rest of the module does.

- http.js - there was a stray console.warn('emit error', err) in an abort-event catch block. Debug leftover, shouldn't reach production. Replaced with a quiet catch.

- AxiosHeaders.js - three places were throwing raw Error or TypeError instead of AxiosError. Swapped them over with ERR_BAD_OPTION_VALUE. Also added the missing AxiosError import (creates a circular dep with AxiosError.js which imports AxiosHeaders, but it works fine at runtime since the throws are inside method bodies, not at module eval time).

- toFormData.js - the circular reference detection was throwing a bare Error. Changed to AxiosError without a code, so it stays distinguishable from the depth-exceeded error that uses ERR_FORM_DATA_DEPTH_EXCEEDED. (There's a test that explicitly checks this distinction.)

- formDataToStream.js - two more raw throws (TypeError and Error) → AxiosError.

- buildURL.js - import self-path ../helpers/AxiosURLSearchParams.js when it lives in the same directory as the importer. Changed to ./AxiosURLSearchParams.js.

- index.d.cts - CanceledError was missing readonly name: 'CanceledError' that index.d.ts already has. Added it to keep the CJS declarations in sync.

Lint passes clean, all 770 unit tests green. Nothing breaking - all changes are either internal (no consumer-facing API change) or type-only.

* Update AxiosHeaders.js

* Update AxiosHeaders.js

* fix: revert breaking error-type changes per review feedback

Reverts AxiosError throws back to native Error/TypeError in AxiosHeaders,
formDataToStream, and toFormData to avoid breaking existing consumers
who catch by constructor name or check isAxiosError().

Adds regression tests for resolveConfig own('params')/own('paramsSerializer')
guard as requested in review.

Removes unused AxiosError imports from AxiosHeaders and formDataToStream.

* docs: add pre-release notes for config hardening

---------

Co-authored-by: Jason Saayman <jasonsaayman@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit::refactor The PR is related to refactoring priority::medium A medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants