fix: support frozen intrinsics when adjusting Error.stackTraceLimit#1
Closed
bweis wants to merge 1 commit into
Closed
fix: support frozen intrinsics when adjusting Error.stackTraceLimit#1bweis wants to merge 1 commit into
bweis wants to merge 1 commit into
Conversation
In hardened/deterministic JavaScript environments (SES "frozen intrinsics", Temporal-style sandboxes), `Error` is frozen and `Error.stackTraceLimit` is read-only. Effect mutates `stackTraceLimit` in several internal spots to capture short/empty stack traces cheaply; under frozen intrinsics those assignments throw, breaking Effect entirely. Add an internal `internal/stackTraceLimit.ts` helper (mirroring Node's own guard) that detects writability once at module load and degrades `set` to a silent no-op when the property can't be modified. Replace the raw mutations across Context.ts, Layer.ts, LayerMap.ts, internal/effect.ts, internal/tracer.ts, HttpApiMiddleware.ts and RpcMiddleware.ts with guarded get/set calls, keeping `new Error()` inline at each call site so captured stack traces still point at the real caller. `unsafeSecureJsonParse` in unstable/ai/Tool.ts imports the same internal helper directly (it lives in the same package here, unlike `@effect/ai` upstream). Ports Effect-TS/effect#6279 to effect-smol. Original change stood up by @arlyon. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 19, 2026
Merged
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.
Ports Effect-TS/effect#6279 to
effect-smol.Upstream PR (same branch, base
Effect-TS/effect-smol:main): Effect-TS#2444Type
Description
In hardened/deterministic JavaScript environments (SES "frozen intrinsics", Temporal-style sandboxes),
Erroris frozen andError.stackTraceLimitis read-only. Effect mutatesstackTraceLimitin several internal spots to capture short or empty stack traces cheaply, using the pattern:In these environments the assignments throw, breaking Effect entirely.
This PR adds
packages/effect/src/internal/stackTraceLimit.ts, which checks writability once at module load (mirroring Node's internal guard) and exposesgetStackTraceLimit()/setStackTraceLimit()helpers wheresetis a silent no-op when the property can't be modified. All raw mutations are replaced with these guarded calls, withnew Error()kept inline at each call site so the captured stack trace still points at the real caller rather than the helper.Call sites updated:
Context.ts,Layer.ts,LayerMap.ts,internal/effect.ts(cause pretty-errors,Effect.fn),internal/tracer.ts,unstable/httpapi/HttpApiMiddleware.ts,unstable/rpc/RpcMiddleware.ts.Differences from the upstream PR
The
effect-smollayout differs fromEffect-TS/effect:internal/effect.ts, publicContext.ts/Layer.ts/LayerMap.ts) rather than split acrosscause/core-effect/runtime/layer/context; there is noMicro.ts.ErrorWithStackTraceLimitinterface and.tsimport extensions.unsafeSecureJsonParse(unstable/ai/Tool.ts) imports the internal helper directly instead of duplicating the guard, becauseailives in the same package here (unlike@effect/aiupstream).Behavior in normal (writable) environments is unchanged. A changeset and a dedicated test (
packages/effect/test/StackTraceLimit.test.ts, covering both the writable and frozen paths) are included; typecheck and lint pass and the affected suites (Cause, Tracer, Context, LayerMap, Effect) are green.Note
The original change was stood up by @arlyon. This description and PR were aided via Claude Code.