fix(rpc): make RpcSerialization.msgPack options configurable#6161
fix(rpc): make RpcSerialization.msgPack options configurable#6161bohdanbirdie wants to merge 1 commit intoEffect-TS:mainfrom
Conversation
|
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.
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 `[]`.
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). |
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