docs(elysia): caution callout for parse: 'none' refactor footgun#1281
docs(elysia): caution callout for parse: 'none' refactor footgun#1281alexkahndev wants to merge 1 commit intopingdotgg:mainfrom
Conversation
The current example uses `(ev) => handlers(ev.request)`, which works
because Elysia's static analyzer (sucrose) doesn't recognize the
property-access shape as body access. If a user refactors to the more
idiomatic destructured form `({ request }) => handlers(request)`, the
analyzer flips `inference.body = true`, Elysia compiles in a
`request.json()` call, and UT's handler receives a consumed stream —
surfacing as a silent empty-body 400.
This change keeps the original example untouched and adds:
- A `<Note>` callout in the docs page explaining the gotcha and showing
the `{ parse: "none" }` workaround for users who do refactor.
- An inline comment in the runnable example noting why the handler
shape is intentional.
`parse: 'none'` is the upstream-recommended fix per elysiajs/elysia#1252
and the same option Elysia uses internally for `.mount()`.
|
|
Someone is attempting to deploy a commit to the Ping Labs Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughDocumentation additions clarifying an Elysia handler-shape pitfall where destructured request parameters cause auto-parsing of request bodies, preventing UploadThing from reading the stream. Includes a code example showing the fix with Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
Greptile SummaryThis PR adds a Confidence Score: 5/5Safe to merge — documentation-only change with no functional modifications. Both changed files are purely additive docs/comment changes. The technical explanation is accurate, the No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Elysia route receives request] --> B{Handler shape?}
B -->|ev handler| C[sucrose: mainParameter is ev\nbody has ev dot - no match]
B -->|destructured handler| D[sucrose: mainParameter is request\nbody has request - matches]
C --> E[inference.body = false\nNo pre-parse injected]
D --> F[inference.body = true\nAll 9 inference flags flipped]
E --> G[UploadThing handler\nreceives intact stream]
F --> H[Elysia injects request.json\nStream consumed before handler]
H --> I[UploadThing gets empty body\nSilent 400 at client]
D --> J{Fix: add third arg\nparse none}
J --> G
Reviews (1): Last reviewed commit: "docs(elysia): caution callout for parse:..." | Re-trigger Greptile |
Summary
The Elysia example currently uses
(ev) => handlers(ev.request), which works fine. But the moment a user refactors either route to the more idiomatic destructured form({ request }) => handlers(request), the route silently breaks: Elysia's static analyzer (sucrose) flipsinference.body = true, Elysia compiles in arequest.json()before the handler runs, and UploadThing's handler receives a consumed stream — surfacing as an empty-body 400 at the client with no actionable log.This PR keeps the working example untouched and adds:
<Note>callout in the Elysia docs section explaining the gotcha and showing the{ parse: "none" }opt-out for users who do refactor.examples/backend-adapters/server/src/elysia.tsnoting why theev.requestshape is intentional.No package changes; no changeset (mirrors the docs-only pattern of #976).
Why this is worth flagging
The failure mode is genuinely hard to debug:
x-uploadthing-versionheader (it never reached UT's handler), so it isn't obviously a UT issue.inference.body = trueis what triggers them in the first place.Most Elysia users naturally write
({ request }) =>over(ev) =>— it's the recommended style across the rest of the Elysia ecosystem and docs. Without this callout, copy-pasting the docs example then "cleaning it up" silently breaks uploads.Root cause (for the record)
node_modules/elysia/dist/sucrose.mjslines 179–198. The relevant regexes:For
(ev) => handlers(ev.request):mainParameter = "ev", body ="handlers(ev.request)"exactParameterrequiresev,orev). Body hasev.→ no match.inference.bodystays false → Elysia doesn't pre-parse → UT works.For
({ request }) => handlers(request):mainParameter = "request", body ="handlers(request)"exactParametermatchesrequest).body.hasBodybecomes true at compose.mjs:258 → Elysia injectsrequest.json()→ stream consumed → UT errors.References
parse: 'none'as the permanent fix for "hand the raw request to a 3rd-party framework" use cases..mount()method usesparse: 'none'for the same reason.Summary by CodeRabbit
.get/.postdefinitions.