Laravel Version
13.12.0
PHP Version
8.5.0
Database Driver & Version
No response
Description
The v13.9.0 release included a fix that changes the serialization of array fields in multipart forms (See PR #59984). As far as I understand, this was intended as a minor fix that shouldn't cause any regressions. But it did break some things, for example in the laravel/ai package.
I haven't looked into this too much, but it seems like some parsers interpret multipart forms differently, and the change in serialization breaks at least some Python parsers.
Here's an AI-generated summary of the issues I've ran into debugging with Gemini:
The Serialization Discrepancy
When passing an array value such as ['timestamp_granularities' => ['segment']] in a multipart request:
Before v13.9.0: Laravel serialized the array by repeating the exact key name:
Content-Disposition: form-data; name="timestamp_granularities"
segment
After v13.9.0: Guzzle delegates serialization to PSR-7, which appends PHP-style brackets [] to the key name:
Content-Disposition: form-data; name="timestamp_granularities[]"
segment
Why this breaks Python / FastAPI / Pydantic APIs
Unlike PHP, many API backends built in Python (using FastAPI, Pydantic, or python-multipart ) do not interpret trailing [] as arrays automatically.
Instead, the parser:
- Looks strictly for the exact parameter name ( timestamp_granularities ).
- Treats timestamp_granularities[] as an unrelated, unknown key and discards it.
- Sees the parameter timestamp_granularities as missing/empty, resulting in 422 Unprocessable Entity validation errors (e.g. timestamp granularity must be set to ['segment'], got [] ).
This regression breaks out-of-the-box integrations with third-party APIs served by Python backends (such as Mistral AI's Voxtral STT).
Steps To Reproduce
I reproduced this error using laravel/ai. You can see more details in this PR: laravel/ai/pull/671
Laravel Version
13.12.0
PHP Version
8.5.0
Database Driver & Version
No response
Description
The
v13.9.0release included a fix that changes the serialization of array fields in multipart forms (See PR #59984). As far as I understand, this was intended as a minor fix that shouldn't cause any regressions. But it did break some things, for example in thelaravel/aipackage.I haven't looked into this too much, but it seems like some parsers interpret multipart forms differently, and the change in serialization breaks at least some Python parsers.
Here's an AI-generated summary of the issues I've ran into debugging with Gemini:
The Serialization Discrepancy
When passing an array value such as ['timestamp_granularities' => ['segment']] in a multipart request:
Before v13.9.0: Laravel serialized the array by repeating the exact key name:
After v13.9.0: Guzzle delegates serialization to PSR-7, which appends PHP-style brackets [] to the key name:
Why this breaks Python / FastAPI / Pydantic APIs
Unlike PHP, many API backends built in Python (using FastAPI, Pydantic, or python-multipart ) do not interpret trailing [] as arrays automatically.
Instead, the parser:
This regression breaks out-of-the-box integrations with third-party APIs served by Python backends (such as Mistral AI's Voxtral STT).
Steps To Reproduce
I reproduced this error using
laravel/ai. You can see more details in this PR: laravel/ai/pull/671