Documentation Index
Fetch the complete documentation index at: https://motiadev-feat-ws-payload-size-limit.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Why this change
Before this release, oversizedtrigger() payloads failed in inconsistent and confusing ways. The Node and Rust SDKs used tokio-tungstenite defaults that quietly accepted large frames; the Python SDK silently inherited the websockets library’s 1 MiB default and snapped at exactly that boundary. The engine had no explicit limit and surfaced any oversize-induced disconnect as the generic invocation_stopped, which gave callers no way to tell “worker crashed” apart from “your payload was too big.”
The result: Python users hit a silent 1 MiB cliff that Node and Rust users never saw, and every language’s failure mode looked like a transient connection drop instead of a programming error.
This release lands a single, configurable ceiling end-to-end:
- The engine enforces it.
- Every SDK defaults to the same value.
- Producers refuse to send oversized messages locally instead of triggering a server-side disconnect.
- A dedicated error code (
invocation_failed_payload_too_large) lets callers branch on it.
What changed
Engine
A newmax_message_size field on the iii-worker-manager config sets the inbound WebSocket message ceiling. It is applied to both WebSocketUpgrade::max_message_size and max_frame_size on every worker connection.
| Code | Meaning |
|---|---|
invocation_failed_payload_too_large | The worker sent a WebSocket message larger than max_message_size. Emitted by cleanup_worker on the failed connection. |
invocation_stopped | Unchanged — still emitted for clean disconnects, shutdown, and EOF. |
recv errors are now logged at WARN with peer / worker_id / error context, so operators can see oversize disconnects without enabling debug logging.
See Error Codes for the full table.
Python SDK
- New
InitOptions.max_message_size: int = 16 * 1024 * 1024. - New
IIIPayloadTooLargeexception (subclass ofValueError) carryingpayload_bytesandlimit_bytes, exported from the package root. - Producer guard runs before every WS send.
Node SDK
- New
InitOptions.maxMessageSize?: number(defaults to 16 MiB). - New
IIIPayloadTooLargeexported class withpayloadBytes/limitBytes. - Producer guard runs before every WS send.
Rust SDK
- New
InitOptions::max_message_size: Option<usize>plusInitOptions::resolved_max_message_size(). DEFAULT_MAX_MESSAGE_SIZEconstant exported from the crate root (16 MiB).- New
IIIError::PayloadTooLarge { actual, limit }variant. - Producer guard runs before every WS send.
Behavior change worth flagging
Python users get a 15× larger default. Before this release, the Python SDK silently inherited thewebsockets library’s 1 MiB max-message-size default, while Node and Rust effectively had no ceiling. Python callers occasionally saw mysterious invocation_stopped errors that turned out to be that hidden 1 MiB cap firing.
After this release, the Python default is 16 MiB, matching Node, Rust, and the engine. Payloads between 1 MiB and 16 MiB that previously failed with invocation_stopped will now succeed.
If you were relying on the implicit 1 MiB ceiling as a safety check, set InitOptions(max_message_size=1024 * 1024) explicitly to preserve the old behavior — but consider switching to channels for any payload that genuinely needs to be that large.
Sizing notes
The 16 MiB default is the serialized WebSocket message size, not your raw application data:- Base64 inflates binary content by ~33%.
- The JSON envelope (function ID, invocation ID, headers, etc.) adds another ~10%.
Migration checklist
- No action required for most users — the new defaults are backward-compatible with payloads under 1 MiB.
- Python users with payloads in the 1–16 MiB range: previously failing calls will now succeed.
- If you raise the SDK limit above 16 MiB, also raise
iii-worker-manager.max_message_sizeon the engine — otherwise the local guard passes and the engine disconnects withinvocation_failed_payload_too_large. - Update error handling to match on
invocation_failed_payload_too_large(engine-side) andIIIPayloadTooLarge/IIIError::PayloadTooLarge(producer-side) where the distinction matters. - For payloads that consistently exceed 16 MiB, migrate to channels.