Skip to content

fix(runtime): strip module shebang, stream large http responses, reject oversized vm.fetch by content-length#130

Merged
NathanFlurry merged 1 commit into
mainfrom
fix/claude-shebang-http-streaming
Jun 25, 2026
Merged

fix(runtime): strip module shebang, stream large http responses, reject oversized vm.fetch by content-length#130
NathanFlurry merged 1 commit into
mainfrom
fix/claude-shebang-http-streaming

Conversation

@NathanFlurry

@NathanFlurry NathanFlurry commented Jun 25, 2026

Copy link
Copy Markdown
Member

Summary

Three runtime fixes (plus a limits-inventory classification) needed to unblock Claude agent sessions and large HTTP responses in the VM.

  1. Shebang stripping (v8-runtime): build_module_source now strips a leading #! shebang line before compiling a module. The patched Claude agent SDK begins with #!/usr/bin/env node; host Node strips it, but the guest V8 module loader did not, so the adapter SyntaxError-crashed on session/new. Adds a unit test (strip_leading_shebang_matches_node).
  2. Streaming large HTTP responses (v8-bridge): ServerResponseBridge now streams a single res.end(body) on a socket-backed server to the connection socket in 256 KiB slices (computing byte length incrementally), instead of buffering the whole body plus its serialize/transmit copies — which tripped the per-isolate heap-limit OOM guard on multi-MB responses. Socket-backed path only; loopback HTTP is unchanged.
  3. Oversized vm.fetch rejection (sidecar): parse_kernel_http_fetch_response rejects a response whose declared Content-Length exceeds VM_FETCH_BUFFER_LIMIT_BYTES before stalling on a body the guest cannot stream through the bounded 4 MiB kernel socket buffer before the request deadline. Uses the hard wire limit, so smaller-but-over-a-configured-limit responses still deliver and hit the existing payload-size check.
  4. limits-inventory: classify DEFAULT_HEAP_LIMIT_MB (policy, wired to VmLimits.js_runtime.v8_heap_limit_mb) and MAX_V8_USERLAND_CODE_BYTES (invariant).

Testing

  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo fmt --check
  • limits_audit 2/2 ✅
  • strip_leading_shebang_matches_node
  • All 8 vm_fetch_kernel_tcp_* tests + http-server tests (incl. normal delivery aae) ✅ — aai oversized-rejection now passes, no regressions
  • Downstream: agent-os claude-session 9/9 + pi-vanilla-bash 3/3 against this build ✅

…ct oversized vm.fetch by content-length

- v8-runtime: strip a leading #!shebang in build_module_source so the patched
  Claude agent SDK (which begins with #!/usr/bin/env node) parses in guest V8
  instead of SyntaxError-crashing the adapter on session/new (host Node strips
  it; the guest loader did not).
- v8-bridge: ServerResponseBridge streams a single res.end(body) to the
  connection socket in bounded slices (incremental byteLength) instead of
  buffering the whole body + its serialize/transmit copies, which tripped the
  isolate heap-limit OOM guard on multi-MB responses. Socket-backed path only;
  loopback http unchanged.
- sidecar: vm.fetch rejects a response whose declared Content-Length exceeds
  VM_FETCH_BUFFER_LIMIT_BYTES before stalling on a body it cannot stream through
  the bounded kernel socket buffer; keeps the per-VM configured-limit payload
  check intact.
- limits-inventory: classify DEFAULT_HEAP_LIMIT_MB (policy) and
  MAX_V8_USERLAND_CODE_BYTES (invariant).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@railway-app railway-app Bot temporarily deployed to secure-exec / secure-exec-pr-130 June 25, 2026 20:08 Destroyed
@railway-app railway-app Bot temporarily deployed to rivet-frontend / secure-exec-pr-130 June 25, 2026 20:09 Destroyed
@NathanFlurry NathanFlurry merged commit 2eb88d8 into main Jun 25, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant