Skip to content

fix(api): make ctx.json() with no arguments read the request body (depends on #2999) - #3010

Merged
kwakayama merged 2 commits into
mainfrom
fix/ctx-json-parses-request-body
Jul 22, 2026
Merged

fix(api): make ctx.json() with no arguments read the request body (depends on #2999)#3010
kwakayama merged 2 commits into
mainfrom
fix/ctx-json-parses-request-body

Conversation

@mattboon

@mattboon mattboon commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

ctx.json() in pages API routes looked like a request-body parser but actually built a JSON Response from undefined. Handlers that wrote const body = await ctx.json() received a Response object, and echoing it back serialized to {}, silently dropping POST payloads.

This PR makes ctx.json arity-based: ctx.json() parses the request body, while ctx.json(data, init?) still builds a JSON Response. The worker-isolation API path now uses the same helper so isolated and in-process handlers behave the same.

Verification

  • deno test --allow-all src/routing/api/context-builder.test.ts
  • deno task lint:sanitizer-baseline
  • deno task lint
  • deno task typecheck

Review status

Score: 94/100. Recommended next step: merge after GitHub required checks finish green.

@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: 55aca343ea

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +23 to +25
json: {
(): Promise<unknown>;
(data: unknown, init?: ResponseInit): Response;

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 Implement ctx.json() in isolated pages routes

With WORKER_ISOLATION_ENABLED=1 and WORKER_ISOLATION_API=1, executePagesRoute() takes the isolated branch (src/routing/api/route-executor.ts:450), where src/security/sandbox/worker-script.ts:457 still builds ctx.json as only a response helper. A pages API handler using the newly supported await ctx.json() in that environment still receives a Response object instead of the parsed body, so POST payloads continue to be dropped under worker isolation; mirror this arity check in the worker context or share the same context builder there.

Useful? React with 👍 / 👎.

@mattboon
mattboon force-pushed the fix/tsx-imports-mdx branch from 6df7b93 to b6d4ac1 Compare July 21, 2026 18:19
@mattboon
mattboon force-pushed the fix/ctx-json-parses-request-body branch from 55aca34 to c5ea111 Compare July 21, 2026 18:19

@kwakayama kwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Score: 84/100

The tests show the intended arity split works: ctx.json() parses the request body, while ctx.json(data, init?) still builds a JSON response. This fixes a real footgun for handlers using the zero-arg form.

Not merge-ready yet:

  • This is stacked on lower open PRs, including blocked/type-failing PRs.
  • The PR status rollup only shows CLA, not full CI.

Architectural watch item: ctx.json now means request parsing or response creation depending only on arity. That may be pragmatic given existing usage, but it is a fragile public boundary and should be documented as an intentional overload.

@mattboon
mattboon force-pushed the fix/tsx-imports-mdx branch from b6d4ac1 to 4566899 Compare July 21, 2026 19:22
@mattboon
mattboon force-pushed the fix/ctx-json-parses-request-body branch from c5ea111 to d223eeb Compare July 21, 2026 19:23
@mattboon
mattboon force-pushed the fix/tsx-imports-mdx branch from 4566899 to 7d862f1 Compare July 21, 2026 19:44
@mattboon
mattboon force-pushed the fix/ctx-json-parses-request-body branch from d223eeb to 10b0811 Compare July 21, 2026 19:44
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from 10b0811 to 6490cad Compare July 21, 2026 20:30
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 7d862f1 to 0d6621f Compare July 21, 2026 20:30
kwakayama
kwakayama previously approved these changes Jul 21, 2026

@kwakayama kwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Follow-up after fixes: approving. The public API docs now explain \ request parsing vs \ response creation, and examples were updated. I also scrubbed real-looking example names to synthetic test data. Score: 91/100. Next step: merge after base stack and checks are green.

@kwakayama

Copy link
Copy Markdown
Contributor

Clean follow-up after the approval above:

Score: 91/100.

Fix added: public docs now explain ctx.json() request parsing vs ctx.json(data, init?) response creation. I also scrubbed real-looking example names to synthetic test data.

Next step: merge after the base stack and refreshed checks are green.

@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from 6490cad to 84b9305 Compare July 21, 2026 20:38
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 0d6621f to 1c906fa Compare July 21, 2026 20:38
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from a829396 to f4f212a Compare July 21, 2026 22:39
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch 2 times, most recently from 4a473a3 to ee402cc Compare July 21, 2026 22:47
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from f4f212a to 4bc6a04 Compare July 21, 2026 22:47
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from ee402cc to edcb779 Compare July 21, 2026 22:57
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from 4bc6a04 to 7ea42f9 Compare July 21, 2026 22:57
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from edcb779 to d054352 Compare July 21, 2026 23:38
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from 7ea42f9 to 1beb02b Compare July 21, 2026 23:38
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from d054352 to 7f53c76 Compare July 21, 2026 23:44
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from 1beb02b to 153b882 Compare July 21, 2026 23:44
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 7f53c76 to 94cb29b Compare July 21, 2026 23:53
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch 2 times, most recently from 7811905 to e321644 Compare July 22, 2026 00:15
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 94cb29b to 36d7973 Compare July 22, 2026 00:15
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from e321644 to bb3bcde Compare July 22, 2026 00:22
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 36d7973 to 17b4f24 Compare July 22, 2026 00:22
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from bb3bcde to a3ed383 Compare July 22, 2026 00:29
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 17b4f24 to 7a3df0c Compare July 22, 2026 00:29
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from a3ed383 to e0f731f Compare July 22, 2026 00:43
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 7a3df0c to daf8bbb Compare July 22, 2026 00:43
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from e0f731f to 4eaf654 Compare July 22, 2026 00:47
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from daf8bbb to 4df9e0e Compare July 22, 2026 00:47
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from 4eaf654 to 3e8f040 Compare July 22, 2026 00:54
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 4df9e0e to 57e5df1 Compare July 22, 2026 00:54
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from 3e8f040 to d962947 Compare July 22, 2026 01:04
@kwakayama
kwakayama force-pushed the fix/tsx-imports-mdx branch from 57e5df1 to 9923c98 Compare July 22, 2026 01:04
Base automatically changed from fix/tsx-imports-mdx to main July 22, 2026 01:10
@kwakayama
kwakayama dismissed their stale review July 22, 2026 01:10

The base branch was changed.

mattboon and others added 2 commits July 22, 2026 03:11
`ctx.json` was a response builder only, so `await ctx.json()` stringified
`undefined` into a Response. Handlers reading a posted payload got a Response
object back, which serialised out as `{}`, and every posted body was silently
dropped.

It is now overloaded on arity: `ctx.json()` parses and returns the request
body, `ctx.json(data, init?)` returns a JSON Response as before.

Worker isolation builds its own API context, so it got the same helper rather
than a second copy of the rule. Under WORKER_ISOLATION_API=1 the duplicate was
still response-only, which would have made a handler behave differently
depending on whether isolation was enabled.

Fixes bug 9 of the reproducer matrix.
Constraint: PR review required the public API overload to be documented, not just covered by tests.

Confidence: high

Scope-risk: narrow

Tested: documentation-only change; existing ctx.json tests cover behavior

Not-tested: docs site build
@kwakayama
kwakayama force-pushed the fix/ctx-json-parses-request-body branch from d962947 to 82d10a5 Compare July 22, 2026 01:12

@kwakayama kwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Score: 94/100

Critical review result: this fixes a real API-route bug. await ctx.json() previously returned a JSON Response built from undefined, so handlers that intended to parse POST JSON silently received a Response object and often serialized {} back to the client. The arity overload is narrow, keeps ctx.json(data, init?) response behavior intact, and covers the sandbox worker path by sharing the helper.

Validation reviewed:

  • deno test --allow-all src/routing/api/context-builder.test.ts
  • deno task lint:sanitizer-baseline
  • deno task lint
  • deno task typecheck

Recommended next step: merge after GitHub required checks complete green.

@kwakayama
kwakayama enabled auto-merge (squash) July 22, 2026 01:13
@kwakayama
kwakayama merged commit 1001d7c into main Jul 22, 2026
28 checks passed
@kwakayama
kwakayama deleted the fix/ctx-json-parses-request-body branch July 22, 2026 01:18
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.

3 participants