Skip to content

fix(guard, runner): enforce http body size and ws msg size#4252

Merged
NathanFlurry merged 5 commits intomainfrom
02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size
Feb 27, 2026
Merged

fix(guard, runner): enforce http body size and ws msg size#4252
NathanFlurry merged 5 commits intomainfrom
02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size

Conversation

@MasterPtato
Copy link
Contributor

@MasterPtato MasterPtato commented Feb 21, 2026

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Fixes RVT-5967

@railway-app
Copy link

railway-app bot commented Feb 21, 2026

🚅 Deployed to the rivet-pr-4252 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-inspector ❌ Build Failed (View Logs) Web Feb 21, 2026 at 1:49 am
frontend-cloud ❌ Build Failed (View Logs) Web Feb 21, 2026 at 1:48 am
ladle ❌ Build Failed (View Logs) Web Feb 21, 2026 at 1:42 am
website ❌ Build Failed (View Logs) Web Feb 21, 2026 at 1:41 am
mcp-hub ✅ Success (View Logs) Web Feb 21, 2026 at 1:41 am

Copy link
Contributor Author

MasterPtato commented Feb 21, 2026

@linear
Copy link

linear bot commented Feb 21, 2026

@claude
Copy link

claude bot commented Feb 21, 2026

PR Review: fix(guard, runner): enforce http body size and ws msg size

Good direction — enforcing size limits at the guard layer is the right architectural approach. A few issues to address before merging.


Bug: Unused import (compile warning / dead code)

In engine/packages/pegboard-runner/src/ws_to_tunnel_task.rs line 9:

use rivet_guard_core::proxy_service::MAX_BODY_SIZE;

This import is never used. The size check at line 791 uses ctx.config().pegboard().runner_http_max_response_body_size() instead of MAX_BODY_SIZE. Either remove the import or use the constant for the check (which would also address the inconsistency noted below).


Required documentation update

CLAUDE.md requires: "When changing actor/runtime limits or behavior that affects documented limits (for example KV, queue, SQLite, WebSocket, HTTP, or timeouts), update website/src/content/docs/actors/limits.mdx in the same change."

limits.mdx currently states 128 MiB for both Max request/response body sizes. This PR enforces a 20 MiB guard-layer limit for non-streaming HTTP bodies. The docs are now incorrect and must be updated.


Orphaned error artifact

engine/artifacts/errors/guard.response_body_too_large.json still exists on disk. The corresponding ResponseBodyTooLarge struct was removed from pegboard-runner/src/errors.rs, but the artifact file was not deleted.


Status code semantics: 413 for all invalid_request_body errors

In guard-core/src/utils.rs:

("guard", "invalid_request_body") => StatusCode::PAYLOAD_TOO_LARGE,

Limited::new(body, MAX_BODY_SIZE).collect() can fail from IO errors (client disconnect mid-stream) in addition to body-too-large errors. Both cases return 413, which is misleading for IO failures. Consider inspecting for LengthLimitError to distinguish the cases, or renaming the error to request_body_too_large to signal intent (there is an existing guard.request_body_too_large.json artifact with exactly that name for the gateway's RequestBodyTooLarge error).


Inconsistent limits between layers

For non-streaming responses, the runner allows up to 128 MiB (runner_http_max_response_body_size default), but guard rejects at 20 MiB when buffering. An actor returning a 50 MiB non-streaming response would pass the runner check but be rejected by guard with BAD_GATEWAY. Streaming bypasses the buffer limit, so this is architecturally sound, but the gap is non-obvious and the unused MAX_BODY_SIZE import suggests the intent may have been to unify these.


Expanded tunnel message check scope (undocumented)

The old code only checked ToServerResponseStart body size. The new tunnel_message_inner_data_len_mk{1,2} functions check all message types including chunks and WebSocket messages. This broader scope is likely correct but was not described in the PR description.


tunnel.ts: size check after full body allocation

In engine/sdks/typescript/runner/src/tunnel.ts:

const body = response.body ? await response.arrayBuffer() : null;
if (body && body.byteLength > MAX_BODY_SIZE) {
    throw new Error("Response body too large");
}

response.arrayBuffer() fully reads the entire response into memory before the size check runs. A 50 MiB response still allocates 50 MiB before being rejected. For meaningful memory protection the check needs to happen while streaming (e.g., count bytes in a TransformStream and abort above the limit).


Minor

  • The typo fix in actor-driver.ts ("immeidatley" → "immediately") is a good catch.
  • Punctuation fix on UpstreamError message (added trailing period) is good for consistency.

@MasterPtato MasterPtato force-pushed the 02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size branch from 855bbaa to 889a15b Compare February 21, 2026 01:48
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4252 February 21, 2026 01:48 Destroyed
"code": "invalid_response_body",
"group": "guard",
"message": "Unable to parse response body."
} No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a newline at the end of the file to fix the 'No newline at end of file' linting error

Spotted by Graphite Agent (based on CI logs)

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@MasterPtato MasterPtato force-pushed the 02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size branch from 889a15b to e89cab8 Compare February 26, 2026 01:12
@MasterPtato MasterPtato force-pushed the 02-19-fix_pegboard_add_threshold_parameters_to_runner_protocol_metadata branch from ce7323c to 30accfe Compare February 26, 2026 01:12
@MasterPtato MasterPtato force-pushed the 02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size branch from e89cab8 to a7065e4 Compare February 26, 2026 02:14
@MasterPtato MasterPtato force-pushed the 02-19-fix_pegboard_add_threshold_parameters_to_runner_protocol_metadata branch 2 times, most recently from 0bb287d to 9c03cf4 Compare February 26, 2026 19:42
@MasterPtato MasterPtato force-pushed the 02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size branch from a7065e4 to 6df70f8 Compare February 26, 2026 19:42
@MasterPtato MasterPtato force-pushed the 02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size branch from 6df70f8 to 350c871 Compare February 27, 2026 00:12
@MasterPtato MasterPtato force-pushed the 02-19-fix_pegboard_add_threshold_parameters_to_runner_protocol_metadata branch from 9c03cf4 to 209ff35 Compare February 27, 2026 00:12
@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 27, 2026

More templates

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@4252

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@4252

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@4252

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@4252

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@4252

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@4252

@rivetkit/sqlite-vfs

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@4252

@rivetkit/traces

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@4252

@rivetkit/workflow-engine

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@4252

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@4252

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@4252

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@4252

commit: 350c871

Base automatically changed from 02-19-fix_pegboard_add_threshold_parameters_to_runner_protocol_metadata to main February 27, 2026 00:29
@NathanFlurry NathanFlurry merged commit caa07f9 into main Feb 27, 2026
16 of 35 checks passed
@NathanFlurry NathanFlurry deleted the 02-20-fix_guard_runner_enforce_http_body_size_and_ws_msg_size branch February 27, 2026 00:30
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.

2 participants