Skip to content

GetIterator on a class declaration throws 'is not iterable' — INT32 ClassRef rejected by js_get_iterator's primitive guard (blocks Effect's yield* SomeTag) #6454

Description

@proggeramlug

Summary

With #6449's fixes applied, effect's api.ts module init now completes and the fiber runtime starts (the effect logger emits), but Layer.launch dies with:

[HH:MM:SS.mmm] ERROR (#0):
  TypeError: is not iterable
      at <anonymous>

Trace

perry_runtime::symbol::iterator::throw_value_not_iterable
js_get_iterator + 1576
perry_closure_node_modules__effect_platform_src_HttpLayerRouter_ts__59
js_native_call_value
perry_closure_node_modules_effect_src_internal_fiberRuntime_ts__20
perry_closure_node_modules_effect_src_Utils_ts__38
perry_closure_node_modules_effect_src_internal_fiberRuntime_ts__19
…
perry_method_…_fiberRuntime_ts__FiberRuntime____computed_method_44208_44229

So a for…of / spread inside @effect/platform/src/HttpLayerRouter.ts is handed a non-iterable. The prime candidate is getMiddleware:

const getMiddleware = (context: Context.Context<never>): Array<middleware.Fn> => {
  let arr = middlewareCache.get(context)          // WeakMap
  if (arr) return arr
  const topLevel = Arr.empty<Array<middleware.Fn>>()
  let maxLength = 0
  for (const [key, value] of context.unsafeMap) { // <-- Map iteration + array destructuring
    
  }

i.e. context.unsafeMap is not iterable (undefined, or a Map that Perry's js_get_iterator doesn't accept). Reached via stack.push(...getMiddleware(depsContext)).

Other iteration sites in that file, for triage: for (const fn of Arr.reverse(middleware)) (line ~212), for (const arr of topLevel) (~807), for (const route of router_.routes) (~1044).

Repro

git clone https://github.com/bjacobso/effect-compiled-experiment && cd effect-compiled-experiment
npm install
perry compile src/effect/web.ts -o dist/web
PORT=3000 ./dist/web

with PR #6449 applied (without it, web.ts fails earlier — see #6438).

Environment

Perry PR #6449 head (3187ef3e5, rebased on origin/main), macOS arm64, coherent full cargo build --release, compiled with auto-optimize.

Context — this is the 4th layer

web.ts has been behind a chain; each layer was a distinct bug, all now fixed in #6449:

  1. TypeError: undefined is not iterable — own statics shared across evaluations of a class expression with heritage
  2. cannot extend "BadArgument" with "BadArgument" — inherited statics resolving through the template's last-wins class_id chain instead of the object's own parent
  3. Cannot convert undefined or null to objectthis bound to the PROTO instead of the receiver for a method inherited by a FUNCTION object (Object.setPrototypeOf(fn, Proto))
  4. this issue

logger.ts and forking.ts from the same repo already run byte-identical to node.

Note

I have not minimized this one yet. If context.unsafeMap is the culprit, the likely question is whether a Map-valued property read through effect's Context returns something js_get_iterator rejects — worth checking a for (const [k, v] of someObj.mapProp) shape (Map behind a property read, with array destructuring in the binding) before assuming it is undefined.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions