fix(api): /stacks/new invalid_form message uses real 50 MiB cap, not 200 MB (B7-P1-1)#208
Merged
Merged
Conversation
…200 MB (B7-P1-1)
POST /stacks/new emitted:
error: "invalid_form"
message: "Request must be multipart/form-data (max 200 MB)"
The "max 200 MB" hint was a lie. The real cap is the global Fiber BodyLimit
of 50 MiB (router.go:169); anything > 50 MiB is rejected upstream by Fiber's
ErrorHandler with `payload_too_large` and never reaches this handler. The
in-handler `invalid_form` arm only fires for malformed multipart bodies
AT OR UNDER 50 MiB.
An agent reading the 200 MB message and building a 100 MB stack tarball got
413 instead of the promised 400 — and a stack-vs-deploy contract drift
(deploy.go correctly says "max 50 MB"). One limit, two truths.
The fix updates stack.go's comment + message to match the real cap and adds
a registry-iterating regression test (rule 18, MULTI-PATH-COVERAGE-RULES.md)
that walks every multipart-upload endpoint emitting `invalid_form` and
asserts the message references 50 (MiB|MB) and does NOT contain known wrong
sizes ("200 MB", "100 MB", "1 GB", etc.). Verified to FAIL pre-fix:
--- FAIL: TestUploadSizeMessage_NoLies (0.08s)
--- FAIL: TestUploadSizeMessage_NoLies//stacks/new (0.00s)
"Request must be multipart/form-data (max 200 MB)" should not contain "200 MB"
…and PASS post-fix.
Coverage block:
Symptom: invalid_form message advertises wrong upload cap
Enumeration: rg -n '200 MB\|200MB\|max 200\|200 MiB' internal/handlers/
Sites found: 1 (stack.go:474,478)
Sites touched: 1
Coverage test: TestUploadSizeMessage_NoLies (iterates deploy.New + stack.New)
Live verified: pending deploy → curl POST /stacks/new with non-multipart body
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
POST /stacks/newadvertised a fake 200 MB upload cap in itsinvalid_formerror message. Real cap is the global FiberBodyLimit = 50 MiBset inrouter.go:169; anything > 50 MiB is rejected upstream by Fiber'sErrorHandlerwithpayload_too_largeand never reaches the handler. An agent that read the 200 MB hint and built a 100 MB tarball got413 payload_too_largeinstead of the promised400 invalid_form. One limit, two truths./deploy/newcorrectly says "max 50 MB" — this PR reconciles stack.go with deploy.go and the router-level ground truth.Files changed
api/internal/handlers/stack.go— message + comment now reference the real 50 MiB aggregate cap, with a back-link to T19 P1-2 (where the global BodyLimit landed) and to this fix.api/internal/handlers/upload_size_message_test.go(new) — registry-iterating regression test (rule 18) that walks every multipart-upload endpoint emittinginvalid_form(deploy.New + stack.New today), drives each to that arm, and asserts the message references 50 (MiB|MB) and contains none of200 MB,200MB,100 MB,1 GB, etc.Test plan
Local — DB-backed:
Test catches the bug — verified by reverting
stack.goand re-running:Re-applying the fix returns
ok.Rule-17 coverage block
Discipline checklist
go testreturned literalokbefore pushfix/api-stack-200mb-lie-2026-05-30→origin/master)Surface check (rule 22)
api/internal/handlers/stack.go— fixedapi/internal/handlers/openapi.go— searched for "200 MB" / "200MB"; only correct "50 MiB" / "50 MB" references presentapi/internal/handlers/deploy.go— already says "50 MB" (was the reference standard)api/internal/handlers/stack.goRedeploy(L1340) — already says "multipart/form-data with a 'manifest' field" (no size lie); registry test does not extend to it today (differentinvalid_formshape, separate path)🤖 Generated with Claude Code