… MiB
The JVM A2A server built its zio-http server from Server.Config.default and
never applied the configured maxRequestBodyBytes. zio-http 3.0.1's default is
RequestStreaming.Disabled(1024*100), so every A2A request was silently capped
at 100 KiB and larger bodies were rejected with HTTP 413 before the handler
ran. This broke file uploads: A2A Parts carry files as base64 fileWithBytes
inside the JSON-RPC body (~33% inflation), so even a few small files tripped
the limit.
- A2AServerLive: chain .disableRequestStreaming(config.maxRequestBodyBytes)
onto Server.Config.default so the configured cap actually applies (keeps
full-body aggregation, which the JSON-RPC routes need).
- A2AServerDefaults: raise MaxRequestBodyBytes from 1 MiB to 64 MiB to cover
inline document uploads after base64 inflation. Clients needing larger
payloads should use fileWithUri references.
The JS/Bun server already enforces this limit manually in readBodyLimited and
shares the same default, so the bump raises its limit too with no code change.
Tests:
- JVM regression (A2AServerLiveSpec): start a real bound zio-http server and
POST a ~200 KiB message/send, asserting 200 + a completed task. The existing
body-limit test calls handleHttp in-process and bypasses the Server.Config
cap, so it never caught this; verified the new test fails without the fix.
- JS parity (A2ARestTransportSpec): accept a ~200 KiB message/send at the
default limit.
Closes #58
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Fixes #58. The JVM A2A server built its zio-http server from
Server.Config.defaultand never applied the configuredmaxRequestBodyBytes. zio-http 3.0.1's default isRequestStreaming.Disabled(1024 * 100), so every A2A request was silently capped at 100 KiB and larger bodies were rejected with HTTP 413 before the handler ran.This broke file uploads: A2A
Parts carry files as base64fileWithBytesinside the JSON-RPC body (~33% inflation), so even a handful of small Markdown files tripped the limit (reported by rtalk: "413 too large for uploads… for trivial ones too").Changes
A2AServerLive.scala— chain.disableRequestStreaming(config.maxRequestBodyBytes)ontoServer.Config.default.binding(...)so the configured cap actually applies.disableRequestStreamingkeeps full-body aggregation (the JSON-RPC routes parse the whole body) at the larger cap instead of 100 KiB.A2AServerDefaults.scala— raiseMaxRequestBodyBytesfrom 1 MiB → 64 MiB to cover inline document uploads after base64 inflation. Clients needing larger payloads should usefileWithUrireferences.JS/Bun parity (no production change needed)
The JS/Bun server already enforces
maxRequestBodyBytesmanually inreadBodyLimited(chunked read + long-arithmetic guard) and shares the sameA2AServerDefaults.MaxRequestBodyBytes, so the default bump raises its limit automatically. Verified, and covered with a parity test.Tests
A2AServerLiveSpec): starts a real bound zio-http server and POSTs a ~200 KiBmessage/send, asserting200+ a completed task. The pre-existing body-limit test callshandleHttpin-process and bypasses theServer.Configcap, so it never caught this. Confirmed the new test fails without the fix (413 → response doesn't parse as JSON-RPC) and passes with it.A2ARestTransportSpec): accepts a ~200 KiBmessage/sendat the default limit.Both suites green:
./mill agent.jvm.test(143/143) and./mill agent.js.test.bunTest(190/190).Follow-ups (out of scope)
fileWithUrifor very large files.🤖 Generated with Claude Code