Relationships
#4234 Worker control WebSocket reports Frame too large and aborts small native dispatches
Opened by nckrtl · 11/1/2026
Bug
An enrolled worker repeatedly disconnects with Disconnected: control socket closed: Frame too large. In-flight native workflow steps then fail with Worker '<worker>' disconnected after step '<step>' had written data — failing the run (write-then-drop). Other no-write dispatches are re-scheduled. The worker reconnects in the same process.
The parser error is confirmed. The offending frame's actual type and byte count are NOT recorded, so legitimate oversize versus malformed framing remains unknown. This report does not claim oversized command stdout or an extension bundle caused it.
Versions
Observed runtime and worker: official 20261031.063736.0-sha.e459d219, source e459d219fe4c9b37c4fdd3f4a7611bf1b6880226, Linux x86_64, remote-only Serve with a native worker. Earlier pinned source was 1602a6172fe5002133a56e8b2da31e90f3fb8b04; no two-version reduced reproduction is claimed.
Observed reproduction
- Run Serve and an enrolled worker on the same official version.
- Dispatch small worker-placed
@swamp/sshexec/script methods and small extension metadata methods. One affected workflow's first step runsnft --check --file -with a small managed-rules input. - The worker reports
control socket closed: Frame too large; the native step fails as write-then-drop, without retained stdout/stderr/exitCode. Subsequent mutation steps are skipped.
This is a repeated captured incident, not yet a deterministic reduced reproduction. No padding experiment or claimed minimum failing size is included.
Two confirmed incidents
- 2026-11-01 08:42:07.755064Z: two SQLite-cleanup children fail at an assets method. Each input is 1,533 bytes; pure evaluation of the same producer writes 1,974 bytes. The cleanup commands never ran. Largest saved method report: 5,498 bytes.
- 2026-11-01 10:24:55.639927Z: the same exact worker socket error recurs during the first
validatestep of another workflow. Serve dispatched its@swamp/ssh.execat 10:24:54.145865Z; native history records the step failed at 10:24:57.193Z and root failed at 10:24:58.816Z. Concurrent SSH script and metadata dispatches also abort. The worker re-enrolls at 10:24:56.878953Z in the same process. Serve's process is unchanged. A later source hot reload starts at 10:26:30Z, after this failure; it cannot explain the earlier disconnect.
No command failure, empty stderr, or successful host mutation is inferred from missing outputs.
Protocol evidence and missing diagnostic
The colon-form error is emitted by worker/connect.ts from Deno WebSocket ErrorEvent/onclose, placing the observed parser failure on the worker receive side of the control socket. Extension bundles and additional files use the HTTP data plane; worker.dispatch carries a fingerprint, not bundle JavaScript. The affected SQLite bundle is 15,687 bytes. Passive header-only samples of other successful dispatches reached 156,487 bytes; those were not the failing frames.
No documented Swamp frame/bundle limit option was found. Deno's fastwebsockets dependency default is 67,108,864 bytes; that is a source default, NOT a measured failing size or documented configurable Swamp setting. No limit was changed. Historical tracing/encoded-byte telemetry was not enabled.
Expected: small valid dispatches stay connected. If a frame is oversized or malformed, expose its direction, protocol message type, advertised and actual byte counts, and a bounded diagnostic. Avoid losing unrelated in-flight work where possible. Please advise how to capture these fields safely without logging secrets or complete payloads.
Open
No activity in this phase yet.
Sign in to post a ripple.