fix(rpc): make RpcSerialization.msgPack options configurable#6161
Conversation
🦋 Changeset detectedLatest commit: 964bb3d The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Uses bun patch to apply the fix from Effect-TS/effect#6161: - msgPack() and layerMsgPack() accept optional msgpackr.Options - Non-incomplete decode errors are rethrown instead of silently returning [] Worker uses RpcSerialization.msgPack({ useRecords: false }) to avoid msgpackr JIT new Function() on CF Workers. Compare with `main` branch for the "before" state.
078fc50 to
5a7e0d4
Compare
|
I'm not sure if the solution is good enough, but I think that the underlying issue is confirmed. I'm rather new to Reproduction repository should be easy to use and try. Tim, let me know what you think (didn't want to ping and create noise). |
CF Workers blocks `new Function()` during request handling (CSP). msgpackr's default build uses JIT code generation via `new Function()` when decoding 4+ same-structure objects in a single unpackMultiple call. This causes @effect/rpc's msgPack serialization to silently return empty responses on deployed CF Workers. Switch to msgpackr's official `index-no-eval` entry point which strips all `new Function()` calls at build time, using the interpreted fallback path instead. Ref: Effect-TS/effect#6161
CF Workers blocks `new Function()` during request handling (CSP). msgpackr's default build uses JIT code generation via `new Function()` when decoding 4+ same-structure objects in a single unpackMultiple call. This causes @effect/rpc's msgPack serialization to silently return empty responses on deployed CF Workers. Switch to msgpackr's official `index-no-eval` entry point which strips all `new Function()` calls at build time, using the interpreted fallback path instead. Ref: Effect-TS/effect#6161
CF Workers blocks `new Function()` during request handling (CSP). msgpackr's default build uses JIT code generation via `new Function()` when decoding 4+ same-structure objects in a single unpackMultiple call. This causes @effect/rpc's msgPack serialization to silently return empty responses on deployed CF Workers. Switch to msgpackr's official `index-no-eval` entry point which strips all `new Function()` calls at build time, using the interpreted fallback path instead. Ref: Effect-TS/effect#6161
…ers (#1163) CF Workers blocks `new Function()` during request handling (CSP). msgpackr's default build uses JIT code generation via `new Function()` when decoding 4+ same-structure objects in a single unpackMultiple call. This causes @effect/rpc's msgPack serialization to silently return empty responses on deployed CF Workers. Switch to msgpackr's official `index-no-eval` entry point which strips all `new Function()` calls at build time, using the interpreted fallback path instead. Ref: Effect-TS/effect#6161 Co-authored-by: Igor Gassmann <igor@igassmann.me>
|
FYI, That said, the configurable |
Adds `makeMsgPack(options)` factory that accepts `msgpackr.Options`,
allowing Cloudflare Workers users to pass `{ useRecords: false }` to
prevent msgpackr's JIT code generation via `new Function()`, which is
blocked during request handling.
Existing `msgPack` and `layerMsgPack` exports are unchanged (no
breaking change).
Also fixes silent error swallowing in the msgPack decode path —
non-incomplete errors are now rethrown instead of returning `[]`.
5a7e0d4 to
d7c7cfa
Compare
|
The upstream fix has been released in msgpackr 1.11.10 (see kriszyp/msgpackr#179). I've opened #6191 to bump the minimum |
* upstream/main: (126 commits) fix(@effect/cli): use Ansi.blackBright for Weak spans so --help is readable on dark terminals (Effect-TS#6208) fix(cli): replace all hyphens in shell completion command names (Effect-TS#6213) Version Packages (Effect-TS#6218) Support null K8s lastTransitionTime values (Effect-TS#6217) Version Packages (Effect-TS#6197) Backport workflow suspension failure fixes (Effect-TS#6196) clone full v4 history Version Packages (Effect-TS#6195) preserve fiber context in HttpLayerRouter.addHttpApi so API-level middleware is applied (Effect-TS#6147) correct typos in source code (receive, separate) (Effect-TS#6110) docs(@effect/vitest): fix return type in fails example (Effect-TS#6163) make RpcSerialization.msgPack options configurable (Effect-TS#6161) update msgpackr to 1.11.10 for Cloudflare Workers compatibility (Effect-TS#6191) fix: floor TestClock nanoseconds before BigInt conversion (Effect-TS#6194) chore: disable TypeScript's nightly workflow (Effect-TS#6193) Version Packages (Effect-TS#6189) (fix: ai-openai) Remove strict param from the OpenAI request body (Effect-TS#6188) Version Packages (Effect-TS#6142) fix(ai-openai): deduplicate response.output items to prevent invalid JSON concatenation (Effect-TS#6178) Change 'in-memory' to 'in_memory' in prompt cache enums (Effect-TS#6187) ...
Fixes #6170
Summary
makeMsgPack(options)factory for creating MessagePack serialization with custom msgpackr optionsmsgPackandlayerMsgPackexports are unchanged (no breaking change)[]Problem
On Cloudflare Workers with
allow_eval_during_startup(default forcompatibility_date >= 2025-06-01),RpcSerialization.msgPacksilently fails when decoding messages containing 3+ objects with the same key structure.Root cause:
new Packr()with no options setsthis.structures = []becauseundefined != falseevaluates totrue. This enables msgpackr's record/structure path. When the Unpackr'sreadObject.countexceeds the JIT threshold (2), msgpackr callsnew Function()to compile a fast reader — which CF Workers blocks during request handling withEvalError: Code generation from strings disallowed for this context.The existing
catch { return [] }inRpcSerialization.msgPacksilently swallows this error, returning an empty response. The caller never receives data.Reproduction
https://github.com/bohdanbirdie/repro-effect-rpc-msgpack-cf-workers
mainbranch — "before" state: reproduces the bug using inline msgpackr code (same asRpcSerialization.msgPack)fixedbranch — "after" state: usesbun patchon@effect/rpcto apply this PR's changes, worker usesRpcSerialization.makeMsgPack({ useRecords: false })Deploy either branch to CF Workers with
npx wrangler deployand curl the endpoint.Fix
Use
makeMsgPackto create a serialization with custom options:This skips
this.structures = []in the Packr constructor, preventing the record/JIT path entirely.Test plan
msgPackandmakeMsgPackwith custom options{ useRecords: false }References
new Function()restriction docsuseRecordsdocsallow_eval_during_startupcompat flag