Skip to content

regression(runtime): natively-compiled cli.js throws "Class extends value does not have valid prototype property" at init (cc-boot layer 4) #8760

Description

@proggeramlug

Summary

After #8726/#8738/#8739 (which fixed the earlier startup blockers), the natively-compiled Claude Code cli.js 2.1.112 bundle boots further but still throws at module init on nearly every command (only --version escapes via early exit):

Uncaught (in promise) TypeError: Class extends value does not have valid prototype property

Node runs the same bundle fine. This is the next layer in the cc-boot chain (each fix reveals the next; agents on #8715/#8730 flagged this would happen).

Throw sites

crates/perry-runtime/src/object/class_registry/parent_static.rs:186 and state.rs:758 — the runtime dynamic class-parent registration. state.rs:758 fires for class X extends <function-valued parent> (a closure) when class_parent_prototype_bits(closure_get_dynamic_prop(parent, "prototype")) returns None; parent_static.rs:186 fires on the bound-function branch when the read prototype isn't object-or-null.

What's ruled out

class X extends {PassThrough,Transform,Readable,Writable} (stream), class X extends EventEmitter, and the aliased form import {PassThrough as PT}; class X extends PT all work correctly on perry (byte-identical to node). So it's a MORE specific parent shape — likely another function-valued/aliased superclass whose .prototype perry doesn't expose, in the spirit of #8738 (which fixed the new <aliased-native> analog). Pinning the exact extends target needs instrumentation.

To pin (fast — runtime-only, so the codegen cache stays valid and re-link is ~49s)

Add a diagnostic at both throw sites printing the parent value's shape (is_closure_ptr? its name/prototype bits? whether it's a native-class registry entry?), rebuild the runtime staticlibs coherently, re-link the cached cli.js object, and run HOME=/tmp/cc_home cc-accept --help to capture the culprit. Then build a reduced synthetic (class X extends <that shape> {}) that reproduces, and fix so perry exposes a valid prototype for it (matching node).

Impact

Blocks booting the natively-compiled Claude Code bundle — layer 4 of the startup chain. Found while verifying #8726/#8738/#8739 against a freshly-built cc binary from origin/main.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions