Skip to content

perry-codegen: Effect — (number).slice is not a function during Schema.ts__init (#680 follow-up, ~310th init) #684

@proggeramlug

Description

@proggeramlug

Summary

After #680 (v0.5.807) fixed the type-only-cycle and namespace-collision blockers exposed by Effect's import {} from "effect", init advances from the 75th call (internal/tracer.ts__init) to the ~310th call (Schema.ts__init) where it throws:

TypeError: (number).slice is not a function
    at <anonymous>
exit: 1

(number).slice means perry's call dispatch is invoking .slice(...) on a JSValue whose tag is INT32_TAG (or a f64 number). Schema.ts has no obvious .slice call at top level — this is likely a deeply-chained String.prototype.slice reaching a value perry tracked as a string but is actually a number.

Repro

mkdir effect-680-followup && cd effect-680-followup
cat > package.json <<JSON
{ "name": "effect-680-followup", "version": "0.0.0", "type": "module",
  "perry": { "compilePackages": ["effect"] } }
JSON
bun add effect@3.21.2

cat > test_bare.ts <<TS
import {} from "effect";
console.log("ok");
TS

perry compile test_bare.ts -o /tmp/out
/tmp/out
# stderr:  TypeError: (number).slice is not a function
#              at <anonymous>

Bisection

lldb on the stripped binary, frame mapping via --keep-intermediates-preserved entry .o:

* thread #1
    frame #6: out`<unnamed Schema.ts__init+5024>          <- bl deep inside Schema.ts__init
    frame #7: out`<unnamed Schema.ts__init>               <- Schema.ts__init at offset +5020
    frame #8: out`__perry_user_main + 1252                <- bl in main returning to +1252 = +0x4e4

Mapping _main + 1252 -> bl @ _main + 1248 (offset 0x4e0) -> objdump -r test_bare_ts.o:

0x4e0  ARM64_RELOC_BRANCH26  _node_modules_effect_src_Schema_ts__init

Then within Schema.ts__init (function start 0x67e58 in its .o), the bl at frame 7's +5020 lands at .o offset 0x67e58 + 0x139c = 0x691f4:

0x691f4  ARM64_RELOC_BRANCH26  _js_native_call_method

So js_native_call_method(receiver, "slice", args) is being called with a non-string receiver. The receiver is what Schema.ts__init computed at that point — likely the result of a chained property access or method call.

Likely shape

Schema.ts has many chained imports and uses several namespace imports (array_, bigDecimal_, chunk_, etc.). The (number).slice likely happens inside a dual()-wrapped function or a top-level pipe() chain where the typing/dispatch lost track of the receiver's actual class. This may be another #680-class namespace collision that the per-namespace map didn't catch (e.g. for a property chain someNs.getter.slice(...) rather than a direct someNs.method(...)).

Status snapshot for #321

Phase Pre-#680 Post-#680 (v0.5.807)
Init position reached 75 (tracer.ts) ~310 (Schema.ts)
Topology cycles broken (tracer first) sound (Context first)
Namespace member collisions random.make -> tracer.make resolved per-namespace
Throw class value is not a function (number).slice is not a function

Refs #321, #671, #680.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions