Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: drop placeholder Content-Type from postForm/putForm/patchForm#10909

Closed
mixelburg wants to merge 2 commits into
axios:v1.xfrom
mixelburg:fix/drop-postForm-content-type-placeholder
Closed

fix: drop placeholder Content-Type from postForm/putForm/patchForm#10909
mixelburg wants to merge 2 commits into
axios:v1.xfrom
mixelburg:fix/drop-postForm-content-type-placeholder

Conversation

@mixelburg

@mixelburg mixelburg commented May 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #10886.

postForm/putForm/patchForm were setting Content-Type: multipart/form-data as a placeholder, relying on adapters to overwrite it with the real boundary later. This breaks on React Native Android — RN is not hasStandardBrowserEnv, so the bare placeholder (without boundary) reaches the wire and Android's networking layer rejects it.

The placeholder is unnecessary: adapters that handle FormData already manage the Content-Type themselves (browser XHR lets the platform set it, Node form-data uses getHeaders(), fetch uses formDataToStream). Dropping it from the overlay config causes no change for those adapters and fixes the RN Android case.


Summary by cubic

Adds transitional.formDataContentType to control the placeholder Content-Type in postForm/putForm/patchForm. Set it to false to drop the placeholder so the adapter/platform sets the correct boundary, fixing React Native Android.

Description

  • Summary of changes
    • Added transitional.formDataContentType (default true).
    • When false, form helpers do not set Content-Type; adapters/platforms set it.
    • Merges instance and per-request transitional; per-request overrides.
  • Reasoning
    • React Native Android rejects multipart/form-data without a boundary.
  • Additional context
    • No change for browsers, Node, or fetch when left at default.
    • Provides a safe migration path.

Docs

Please update /docs/ to cover transitional.formDataContentType with global and per-request examples, and recommend setting it to false on React Native Android.

Testing

Added tests/unit/formMethods.test.js:

  • Default: helpers set placeholder multipart/form-data.
  • Opt-out (per-request and global): header not set.
  • Per-request opt-out overrides instance default.
  • Non-form post unaffected.

Semantic version impact

Minor: adds a backward-compatible flag with the default preserving current behavior.

Written for commit 4ded3d5. Summary will update on new commits.

Review in cubic

@mixelburg mixelburg requested a review from jasonsaayman as a code owner May 18, 2026 22:09

@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 1 file

Confidence score: 5/5

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

Re-trigger cubic

@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 think we may need a transitional property; otherwise, this would be a breaking change we cannot release. If we can address that and then add some very solid testing here that would probably help this land!

Comment thread lib/core/Axios.js Outdated
Comment thread lib/core/Axios.js
@jasonsaayman jasonsaayman added the status::changes-requested A reviewer requested changes to the PR label 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.

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

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/unit/formMethods.test.js">

<violation number="1" location="tests/unit/formMethods.test.js:22">
P1: These tests assert the old placeholder `Content-Type: multipart/form-data` behavior by default, which conflicts with the PR’s fix to stop injecting that header.</violation>
</file>

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

Re-trigger cubic

Comment thread lib/core/Axios.js
@@ -0,0 +1,116 @@
/**

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.

P1: These tests assert the old placeholder Content-Type: multipart/form-data behavior by default, which conflicts with the PR’s fix to stop injecting that header.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/unit/formMethods.test.js, line 22:

<comment>These tests assert the old placeholder `Content-Type: multipart/form-data` behavior by default, which conflicts with the PR’s fix to stop injecting that header.</comment>

<file context>
@@ -0,0 +1,116 @@
+
+describe('form method helpers (postForm/putForm/patchForm)', () => {
+  describe('default behaviour (transitional.formDataContentType = true)', () => {
+    it('postForm sets placeholder Content-Type: multipart/form-data by default', async () => {
+      let capturedConfig;
+      const instance = axios.create({ adapter: (cfg) => { capturedConfig = cfg; return mockAdapter(cfg); } });
</file context>

@DigitalBrainJS

Copy link
Copy Markdown
Collaborator

Without a header placeholder, there would be no sense in the existence of these methods.

Axios serializes the request body based on the headers, and the payload object is serialized as a form, not as JSON, when the form header is set. That's why the header placeholder is highly necessary. These methods were introduced to avoid manually setting this header. Otherwise, it would be necessary to introduce an option like requestType, and then decide how to handle conflicting settings when the user passed the application/json header but also set requestType: 'formdata'.

axios.post('https://httpbin.org/post', { x: 1 }); // => application/json

axios.postForm('https://httpbin.org/post', { x: 1 }); // => multipart/form-data

So, issues of correctly setting headers for the platform should be addressed in the adapter itself. When these methods were introduced, FormData in ReactNative required the Content-Type: multipart/form-data header, without a boundary—at least, that was the result of testing conducted on hardware. I suspect some changes were made to the RN network stack, and the actual behavior depends on the version, although I haven't checked the source code of their HTTP modules for changes since then.

@jasonsaayman

Copy link
Copy Markdown
Member

@mixelburg, please let us know if you can address the cubic review comments and look at @DigitalBrainJS comments, please.

@jasonsaayman jasonsaayman added status::stale This PR or issue is deemed stale. Feedback has not been provided in 2 weeks. commit::fix The PR is related to a bugfix and removed priority::medium labels Jun 14, 2026
…tchForm

Adds `transitional.formDataContentType` (default `true`) to control whether
postForm/putForm/patchForm inject the placeholder `Content-Type: multipart/form-data`
header. Set to `false` globally or per-request to let the adapter/platform set the
correct Content-Type with boundary — fixes React Native Android where the placeholder
without a boundary is rejected by the networking layer (issue axios#10886).

This keeps backward compat (existing code unaffected by default) while providing a
migration path before a future major-version default flip to `false`.
@mixelburg mixelburg force-pushed the fix/drop-postForm-content-type-placeholder branch from ab1fd44 to 4ded3d5 Compare June 17, 2026 00:13
@jasonsaayman jasonsaayman added type::breaking The PR introduces breaking changes status::blocked This PR or issue is deemed to be blocked labels Jun 17, 2026
@jasonsaayman

Copy link
Copy Markdown
Member

Closing see #10898

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 status::blocked This PR or issue is deemed to be blocked status::changes-requested A reviewer requested changes to the PR status::stale This PR or issue is deemed stale. Feedback has not been provided in 2 weeks. type::breaking The PR introduces breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drop forced bare multipart/form-data placeholder header in postForm/putForm/patchForm (breaks RN Android)

3 participants