Skip to content

[WRONG BRANCH] fix(server): bound raised inbound body concurrency - #482

Draft
luvs01 wants to merge 1 commit into
mainfrom
codex/propose-fix-for-memory-admission-vulnerability
Draft

[WRONG BRANCH] fix(server): bound raised inbound body concurrency#482
luvs01 wants to merge 1 commit into
mainfrom
codex/propose-fix-for-memory-admission-vulnerability

Conversation

@luvs01

@luvs01 luvs01 commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Motivation

  • Mitigate a new availability regression introduced by raising the per-request inbound body cap up to 512 MiB, which allowed unauthenticated loopback callers to trigger multi-gigabyte transient allocations.
  • Prevent concurrent raised-limit requests from multiplying peak memory (reader materializes wire, decoded, text, parsed graph, and observational re-encodes).
  • Preserve existing behavior for ordinary requests and keep undocumented routes (image/search) at their previous route-specific limits.

Description

  • Add a process-wide inbound decoded-body admission gate with a shared 512 MiB budget and a reserveInboundBodyCapacity helper that readers call before consuming large bodies; callers above the default cap receive a retryable 503 server_busy (InboundBodyCapacityError) when the aggregate budget is exhausted.
  • Thread admission into the JSON reader (readBoundedJsonRequestBody) so each raised-limit reader reserves and releases its configured allowance; default-limit readers (<= 256 MiB) keep previous concurrency semantics.
  • Reduce peak allocations by removing redundant UTF-8 re-encoding / JSON.stringify measurement copies and using the decoded byte-length as a conservative accounting proxy for translator-budget observation.
  • Do not apply the configured maxInboundBodyBytes to image and search handlers; restore those routes to the prior route-specific limit by using the shared reader default instead of resolving the opt-in value.
  • Map the new capacity refusal to a 503 server_busy response in the request error decoder, add a focused regression test proving concurrent raised-limit readers are serialized, and update docs to document scope and aggregate admission behavior.

Testing

  • Ran focused suites: bun test tests/usage/request-decompress.test.ts tests/server/server-request-body-size.test.ts tests/server/server-images.test.ts tests/server/server-search.test.ts --timeout 30000 and observed the affected tests pass (focused run: 149 passed for the changed areas).
  • Typecheck: bun x tsc --noEmit completed successfully.
  • Docs: built the site (cd docs-site && bun install --frozen-lockfile && bun run build) and the site build completed successfully.
  • Privacy and hygiene: bun run privacy:scan ran and passed; git diff --check showed no extra whitespace/errors.

Note: a repository-wide parallel bun run test was attempted but stopped after unrelated environment/fixture issues appeared; the focused tests covering these changes are green on the repository-pinned Bun runtime used for validation.


Codex Task

@github-actions

Copy link
Copy Markdown

Deterministic PR hygiene checks passed.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-11T12:10:15.606976Z 80905d1 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added the bug Something isn't working label Sep 11, 2026
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: b072ece3-68cc-49e5-80e4-8faa3168fdfa


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot changed the title fix(server): bound raised inbound body concurrency [WRONG BRANCH] fix(server): bound raised inbound body concurrency Sep 11, 2026
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

⏳ DRAFT

  • wrong target branch (main); retarget to dev.

What to do

  • Retarget this PR to dev — all contributions go to dev.

Its title has been prefixed with [WRONG BRANCH].
This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.

@github-actions
github-actions Bot marked this pull request as draft September 11, 2026 12:06

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80905d11af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

releaseText?.();
releaseDecoded?.();
releaseRaw?.();
releaseInboundCapacity();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the admission lease while the parsed body is retained

When maxInboundBodyBytes is raised and a large request finishes parsing but then waits in routing or upstream work, this finally immediately frees its entire process-wide reservation even though the returned object remains live; for example, responses/core.ts stores it in parsed._rawBody and later awaits quota and entitlement work. Subsequent requests can therefore parse and retain additional 300–512 MiB object graphs, so fast uploads followed by slow upstream calls can still accumulate multi-gigabyte bodies despite the advertised 512 MiB budget. Transfer the lease to the request lifecycle, or otherwise keep accounting for the retained parsed graph until request processing releases it.

Useful? React with 👍 / 👎.

Comment on lines +60 to +61
if (maxBytes > MAX_CONCURRENT_INBOUND_BODY_BYTES - reservedInboundBodyBytes) {
throw new InboundBodyCapacityError();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve capacity errors across Chat and Claude wrappers

When another raised-limit reader holds capacity, /v1/chat/completions and /v1/messages do not return the intended retryable 503 server_busy: readChatBody and readAnthropicBody catch this new error and wrap it as ChatCompletionsRequestError or AnthropicRequestError, whose handlers return 400. Only the Responses error decoder recognizes the class, so these clients treat temporary overload as an invalid request and may not retry. Let both wrappers preserve InboundBodyCapacityError and map it to each protocol's 503 representation.

AGENTS.md reference: src/AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aardvark bug Something isn't working codex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant