fix(deps): update dependency effect to v3.20.0 [security] - autoclosed#633
Closed
renovate[bot] wants to merge 1 commit intomainfrom
Closed
fix(deps): update dependency effect to v3.20.0 [security] - autoclosed#633renovate[bot] wants to merge 1 commit intomainfrom
renovate[bot] wants to merge 1 commit intomainfrom
Conversation
✅ Deploy Preview for angry-raman-7c44f6 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
3.19.19→3.20.0GitHub Vulnerability Alerts
CVE-2026-32887
Versions
effect: 3.19.15@effect/rpc: 0.72.1@effect/platform: 0.94.2@clerk/nextjs: 6.xRoot cause
Effect's
MixedSchedulerbatches fiber continuations and drains them inside a single microtask or timer callback. TheAsyncLocalStoragecontext active during that callback belongs to whichever request first triggered the scheduler's drain cycle — not the request that owns the fiber being resumed.Detailed mechanism
1. Scheduler batching (
effect/src/Scheduler.ts,MixedScheduler)scheduleTaskonly callsstarve()whenrunningisfalse. Subsequent tasks accumulate inthis.tasksuntilstarveInternaldrains them all. ThePromise.then()(orsetTimeout) callback inherits the ALS context from whichever call site created it — i.e., whichever request's fiber first setrunning = true.Result: Under concurrent load, fiber continuations from Request A and Request B execute inside the same
starveInternalcall, sharing a single ALS context. If Request A triggeredstarve(), then Request B's fiber reads Request A's ALS context.2.
toWebHandlerRuntimedoes not propagate ALS (@effect/platform/src/HttpApp.ts:211-240)Effect's own
Context(containingHttpServerRequest) is correctly set per-request. But the Node.js ALS context — which frameworks like Next.js, Clerk, and OpenTelemetry rely on — is not captured at fork time or restored when the fiber's continuations execute.3. The dangerous pattern this enables
The
async () => auth()thunk executes when the fiber continuation is scheduled byMixedScheduler. At that point, the ALS context belongs to an arbitrary concurrent request.Reproduction scenario
Minimal reproduction
Impact
auth()returns wrong user's sessioncookies()/headers()from Next.js read wrong requestWorkaround
Capture ALS-dependent values before entering the Effect runtime and pass them via Effect's own context system:
Suggested fix (for Effect maintainers)
Option A: Propagate ALS context through the scheduler
Capture the
AsyncLocalStoragesnapshot when a fiber continuation is scheduled, and restore it when the continuation executes:AsyncLocalStorage.snapshot()(Node.js 20.5+) returns a function that, when called, restores the ALS context from the point of capture. This ensures each fiber continuation runs with its originating request's ALS context.Trade-off: Adds one closure allocation per scheduled task. Could be opt-in via a
FiberRefor scheduler option.Option B: Capture ALS at
runForkand restore per fiber stepWhen
Runtime.runForkis called, capture the ALS snapshot and associate it with the fiber. Before each fiber step (in the fiber runtime'sevaluateEffectloop), restore the snapshot.Trade-off: More invasive but provides correct ALS propagation for the fiber's entire lifetime, including across
flatMapchains andEffect.tryPromisethunks.Option C: Document the limitation and provide a
contextinjection APIIf ALS propagation is intentionally not supported, document this prominently and provide a first-class API for
toWebHandlerto accept per-request context. The existingcontext?: Context.Context<never>parameter on the handler function partially addresses this, but it requires callers to know about the issue and manually extract values before entering Effect.Related
AsyncLocalStoragedocs: https://nodejs.org/api/async_context.htmlAsyncLocalStorage.snapshot(): https://nodejs.org/api/async_context.html#static-method-asynclocalstoragesnapshotcookies(),headers(),auth()in App RouterFiberRefpropagation for this)POC replica of my setup
Used util functions
The actual effect that was run within the RPC context that the bug was found
Release Notes
Effect-TS/effect (effect)
v3.20.0Compare Source
Minor Changes
8798a84Thanks @mikearnaldi! - Fix scheduler task draining to isolateAsyncLocalStorageacross fibers.Patch Changes
#6107
fc82e81Thanks @gcanti! - BackportTypes.VoidIfEmptyto 3.x#6088
82996bcThanks @taylorOntologize! - Schema: fixSchema.omitproducing wrong result on Struct withoptionalWith({ default })and index signaturesgetIndexSignaturesnow handlesTransformationAST nodes by delegating toast.to, matching the existing behavior ofgetPropertyKeysandgetPropertyKeyIndexedAccess. Previously,Schema.omiton a struct combiningSchema.optionalWith(with{ default },{ as: "Option" }, etc.) andSchema.Recordwould silently take the wrong code path, returning a Transformation with property signatures instead of a TypeLiteral with index signatures.#6086
4d97a61Thanks @taylorOntologize! - Schema: fixgetPropertySignaturescrash on Struct withoptionalWith({ default })and other Transformation-producing variantsSchemaAST.getPropertyKeyIndexedAccessnow handlesTransformationAST nodes by delegating toast.to, matching the existing behavior ofgetPropertyKeys. Previously, callinggetPropertySignatureson aSchema.StructcontainingSchema.optionalWithwith{ default },{ as: "Option" },{ nullable: true }, or similar options would throw"Unsupported schema (Transformation)".#6097
f6b0960Thanks @gcanti! - Fix TupleWithRest post-rest validation to check each tail index sequentially.Configuration
📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.