With --body-limit 200MB set (verified identical behavior via the flag and via JSS_BODY_LIMIT=200MB), pushing solid-chat/app (13.6MB repo) via jss install still produces 413 responses on some of the git-receive-pack POSTs (jss 0.0.207):
A 13.6MB pack should never trip a 200MB cap, so something else is rejecting those POSTs. Candidates worth checking:
size-string parsing of the limit ("200MB" → parseSize) silently failing for some path and falling back to a smaller route-level cap
a per-route/route-config bodyLimit on the git handler that doesn't inherit the global override
git's multi-POST behavior (probe + pack, or per-branch packs in the dual-push) where one POST hits a different limit
Despite the 413s, the working tree extracts and the app serves — which turns this into a misleading-failure UX (see companion issue on jss install reporting).
Also noticed: jss start --print-config doesn't include bodyLimit, which made diagnosing this harder — worth adding while in here.
Repro: fresh pod jss start --port 5778 --root /tmp/x --idp --single-user --single-user-password me --git --body-limit 200MB, then mkdir -p /tmp/x/public/apps and jss install --pod http://localhost:5778 "solid-chat/app=chat".
Root cause found — the limit was never raised. bin/jss.js defines --body-limit and loadConfig parses it (flag and JSS_BODY_LIMIT both reach config.bodyLimit), but the explicit options object passed to createServer() in the start command omits bodyLimit, so src/server.js falls back to defaults.bodyLimit (10MB) unconditionally on the CLI path. The #474 knob is dead wiring; only programmatic createServer({ bodyLimit }) works.
The "residual 413s at 200MB" in this issue's title are therefore just the 10MB default doing its job. GIT_TRACE_CURL shows the exact mechanics of the 2×200/2×413 pattern:
=> POST .../git-receive-pack Content-Length: 4 ← git's probe
<= HTTP/1.1 200 OK
=> POST .../git-receive-pack Transfer-Encoding: chunked ← the real pack (13.6MB)
<= HTTP/1.1 413 Payload Too Large ← killed at 10MB mid-stream
Fix: add bodyLimit: config.bodyLimit, to the createServer() options in bin/jss.js's start command. A regression test could assert that --body-limit 1KB rejects a 2KB PUT while --body-limit 100MB accepts it (proving the flag reaches Fastify).
Related latent issue while in src/handlers/git.js: the CGI env sets CONTENT_LENGTH: request.headers['content-length'] || '0' — for chunked requests (which is what git sends for any pack > 1MB http.postBuffer) there is no Content-Length header, so http-backend is told 0 even though the full buffered body is written to its stdin. It happens to work today, but it's worth aligning with the buffered length (request.body?.length) when fixing the limit.
Activity
melvincarvalho commented on Jun 11, 2026
Root cause found — the limit was never raised. bin/jss.js defines --body-limit and loadConfig parses it (flag and JSS_BODY_LIMIT both reach config.bodyLimit), but the explicit options object passed to createServer() in the start command omits bodyLimit, so src/server.js falls back to defaults.bodyLimit (10MB) unconditionally on the CLI path. The #474 knob is dead wiring; only programmatic createServer({ bodyLimit }) works.
The "residual 413s at 200MB" in this issue's title are therefore just the 10MB default doing its job. GIT_TRACE_CURL shows the exact mechanics of the 2×200/2×413 pattern:
Fix: add bodyLimit: config.bodyLimit, to the createServer() options in bin/jss.js's start command. A regression test could assert that --body-limit 1KB rejects a 2KB PUT while --body-limit 100MB accepts it (proving the flag reaches Fastify).
Related latent issue while in src/handlers/git.js: the CGI env sets CONTENT_LENGTH: request.headers['content-length'] || '0' — for chunked requests (which is what git sends for any pack > 1MB http.postBuffer) there is no Content-Length header, so http-backend is told 0 even though the full buffered body is written to its stdin. It happens to work today, but it's worth aligning with the buffered length (request.body?.length) when fixing the limit.
Wire --body-limit into createServer; real CONTENT_LENGTH for chunked …
bump version to 0.0.208