Summary
The last standing failure of effect-compiled-experiment web.ts (after #6449 / #6459 / #6460 / #6463+#6466 / #6465+#6470 / #6469+#6474): startup dies with
Error: Not a valid effect: undefined (fiberRuntime.ts:1422)
Root of the poisoned value, isolated by three probes:
probe43 — the poisoned binding
Walking web.ts's layer graph binding-by-binding: everything matches node except
HealthLive node: object (a Layer) perry: function
HealthLive = HttpApiBuilder.group(Api, "health", ...) — and group returns Router.use((router) => ...) where Router is class Router extends HttpRouter.Tag("@effect/platform/HttpApiBuilder/Router")<Router>() {}.
probe44 — Tag statics misbehave
Recreating the Tag shape directly (class R2 extends HttpRouter.Tag("probe44/R2")<R2>() {}):
| check |
node |
perry |
pipe(1, f, g) / 4 fns / method-style .pipe |
✓ |
✓ (all fine) |
R2.key |
✓ |
✓ |
R2.Live |
Layer |
Layer ✓ |
R2.use(f) |
Layer |
function (isLayer false) |
R2.unwrap(f) |
Layer object |
function |
use is an own-prop ARROW on the factory's TagClass (TagClass_.use = (f) => TagClass_.pipe(Effect.flatMap(f), Layer.scopedDiscard, Layer.provide(TagClass_.Live))), inherited by R2 through the parent function object. The returned function is consistent with the pipe chain's LAST stage (Layer.provide(live), a data-last curried fn) never being applied — i.e. TagClass_.pipe(...) misfired on the receiver/arguments. TagClass's prototype is Object.getPrototypeOf(Context.GenericTag(id)) (a two-hop chain to Pipeable's pipe() { return pipeArguments(this, arguments) }).
probe45 — a minimal this-drop divergence in the same family
const Proto: any = { collect(this: any, ...args: any[]) { return [this?.tag, args.length, ...args] } }
function F() {}; Object.setPrototypeOf(F, Proto); (F as any).tag = "fn-recv"
const O: any = { tag: "obj-recv" }; Object.setPrototypeOf(O, Proto)
(F as any).collect(10, 20, 30) // node ["fn-recv",3,10,20,30] | perry ["fn-recv",3,10,20,30] ✓
O.collect(10, 20, 30) // node ["obj-recv",3,10,20,30] | perry ["null",3,10,20,30] ✗
O.fixed(1, 2) // same: this dropped (null) for the OBJECT receiver
A method inherited through Object.setPrototypeOf(plainObject, proto) runs with this = undefined under perry (function-object receivers, own-prop closures, and arguments-based variadics all work). This is the same resolution family pipeArguments(this, arguments) sits in — with this undefined mid-chain, effect's Pipeable composition returns the wrong stage.
Impact
HttpApiBuilder.group(...) returns a function instead of a Layer, and the poison propagates lazily until the fiber run loop rejects an undefined — blocking the web.ts app (the 4th of the effect repro; the other three are byte-identical to node).
Repro files: probes 43/44/45 as above (no server needed for 44/45).
Summary
The last standing failure of effect-compiled-experiment
web.ts(after #6449 / #6459 / #6460 / #6463+#6466 / #6465+#6470 / #6469+#6474): startup dies withRoot of the poisoned value, isolated by three probes:
probe43 — the poisoned binding
Walking web.ts's layer graph binding-by-binding: everything matches node except
HealthLive = HttpApiBuilder.group(Api, "health", ...)— andgroupreturnsRouter.use((router) => ...)whereRouterisclass Router extends HttpRouter.Tag("@effect/platform/HttpApiBuilder/Router")<Router>() {}.probe44 — Tag statics misbehave
Recreating the Tag shape directly (
class R2 extends HttpRouter.Tag("probe44/R2")<R2>() {}):pipe(1, f, g)/ 4 fns / method-style.pipeR2.keyR2.LiveR2.use(f)R2.unwrap(f)useis an own-prop ARROW on the factory's TagClass (TagClass_.use = (f) => TagClass_.pipe(Effect.flatMap(f), Layer.scopedDiscard, Layer.provide(TagClass_.Live))), inherited byR2through the parent function object. The returned function is consistent with the pipe chain's LAST stage (Layer.provide(live), a data-last curried fn) never being applied — i.e.TagClass_.pipe(...)misfired on the receiver/arguments.TagClass's prototype isObject.getPrototypeOf(Context.GenericTag(id))(a two-hop chain to Pipeable'spipe() { return pipeArguments(this, arguments) }).probe45 — a minimal
this-drop divergence in the same familyA method inherited through
Object.setPrototypeOf(plainObject, proto)runs withthis= undefined under perry (function-object receivers, own-prop closures, andarguments-based variadics all work). This is the same resolution familypipeArguments(this, arguments)sits in — withthisundefined mid-chain, effect's Pipeable composition returns the wrong stage.Impact
HttpApiBuilder.group(...)returns a function instead of a Layer, and the poison propagates lazily until the fiber run loop rejects anundefined— blocking theweb.tsapp (the 4th of the effect repro; the other three are byte-identical to node).Repro files: probes 43/44/45 as above (no server needed for 44/45).