Repository navigation
Show the real error when a 4xx carries no validation bag - #285
datashaman wants to merge 2 commits into
Conversation
|
We hit the same thing this morning, and I think I found what's actually behind the empty 4xx, so the message fix here is treating the symptom. 1.70.4 allows Guzzle 8, which pulls in guzzlehttp/psr7 3. psr7 3 preserves the HTTP method casing ( That's why |
|
Confirming the same failure on our side, with the same timeline.
So the Guzzle 8 / User-Agent observation matches what we see. Happy to test a build against our environment if that helps narrow it down on the API side. |
|
You're right, and my note about the User-Agent was wrong — thanks for chasing it down properly. I verified your diagnosis end to end:
// psr7 2.13.1
self::warnOnMethodCasingChange($method);
$this->method = Utils::asciiToUpper($method);
// psr7 3.1.0
$this->method = $method;Capturing the request line against a local socket, calling it the way And your curl reproduction against the real endpoint: For the record on how I got it wrong: my earlier capture used Worth adding that the choke point is narrow. All 88 lowercase call sites go through On this PR: agreed it's the symptom, not the cause, and it shouldn't be merged as a fix for the deploy breakage. I'd still argue it earns its place — with it, that 400 surfaces as instead of a bare "Whoops!", which points straight at the edge rather than at the app, and is what would have made this a five-minute diagnosis for both of us. I've pushed a tweak to collapse whitespace so an HTML page reads on one line. Happy to add the |
|
Following up: the lowercase-method explanation from @maliknikolaj matches our failure exactly, so please disregard the User-Agent line in my comment above. Reproduced from our side as well: |
|
Opened #286 with the To keep the two straight for whoever reviews:
They're independent, so #286 can go in on its own. |
|
@datashaman No need to close anything, #286 is exactly the fix I'd have opened and it's in the right place. Thanks for picking it up and for the credit. Hopefully both land soon. |
|
Thanks for your pull request to Laravel! I appreciate you taking the time to submit this; however, it appears this contribution may have been primarily AI-generated without careful human review and consideration. We've found that AI-generated code often doesn't align well with Laravel's conventions, architectural decisions, and the specific context of what we're trying to accomplish with the framework. Quality contributions require thoughtful human insight into the codebase. If you're interested in contributing to Laravel, I'd encourage you to familiarize yourself with the existing codebase, engage with the community, and submit PRs that reflect your own understanding and careful consideration of the problem you're solving. |
displayValidationErrors()assumes every 400 / 422 carries a Laravel validation bag:When the body is empty or is not JSON,
json_decodereturnsnull, the offset access emitsTrying to access array offset on null, and the user is left with a bareWhoops! There were some problems with your request.followed by nothing. The response that would have explained the failure is discarded.That is the entire output. There is nothing to act on and nothing to search for.
We hit this on production deploys, where the first call
vapor deploymakes —POST /api/projects/{id}/environments/{env}/linted-manifest— started coming back as an empty-bodied 4xx, so every deploy died about a second in with only the message above. Diagnosing it meant reading the CLI source and replaying the request by hand.What this changes
displayValidationErrors()now falls back through the response instead of assuming its shape:messageThe validation-bag path is unchanged, so normal output is identical.
Incidental observation, not fixed here
The empty-bodied 4xx began for us the moment v1.70.4 was installed, which widened the guzzle constraint to allow
^8.0(#284) and moved us from guzzle 7.15.5 to 8.1.0. Replaying the request under both versions against a socket, the bytes are identical apart fromUser-Agent: GuzzleHttp/7becomingGuzzleHttp/8. Pinning back to 1.70.3 restored deploys.I can't see the API side, so I can't say whether the User-Agent is what is being rejected — flagging it in case it's useful. #284's test plan reasonably covered the client API surface, but the suite is mocked and never exercises the real endpoint, so a server-side rejection would not have shown up in CI.
Tests
Four cases covering the validation bag,
message-only, non-JSON, and empty bodies. The full suite passes (60 tests). phpstan reports the same 106 pre-existing errors before and after, none of them in this file.