Skip to content

cc -p fails with "prompt is not a function": a user-defined async method on an object literal is invisible to typed-feedback native dispatch (blocks #9949 rows) #11559

Description

@proggeramlug

With #11556 applied, claude-code 2.1.112 starts (--help works) but -p "say hi" fails immediately:

prompt is not a function

This blocks every cc runtime measurement that needs a turn, including the four-turn tenuring rows for #9949 — those drive cc through -p, so they cannot run until this is fixed.

Caught in gdb on a symbolized build, breaking on every copy of the throw:

#0  js_throw_type_error_not_a_function
#1  js_native_call_method
#2  js_typed_feedback_native_call_method_by_id
#3  perry_fn_cli_2_1_112_js__aMA
#4  … cli_2_1_112_js closures …
#7  perry_runtime::promise::microtasks::pump_protected
#10 perry_runtime::promise::microtasks::run_microtasks
#11 main

So a typed-feedback native method call by id for the method prompt found a receiver that does not carry it, during microtask drain (hence no Uncaught prefix difference — it is thrown inside a promise job).

What prompt is in this bundle

Not a global. grep finds 48 object-literal method definitions of the form

{ …, async description(){ return … }, async prompt(){ return … }, get inputSchema(){ … }, … }

i.e. each tool descriptor carries its own async prompt(). There is no globalThis.prompt, no window.prompt, and no typeof prompt guard anywhere in the bundle, and perry defines no global prompt either. So the failing call is someToolDescriptor.prompt(), and the defect is that a user-defined async method on a plain object literal is not found by the typed-feedback native-method dispatch.

Reproduce

PERRY_RUNTIME_DIR=$PWD/target/release \
  ./target/release/perry compile --no-auto-optimize --enable-wasm-runtime cli_2.1.112.js -o cc
HOME=/tmp/cc_home ./cc -p "say hi"      # prompt is not a function
HOME=/tmp/cc_home ./cc --help           # works

Verified on fix/11499-static-write-instance-accessor (main d57f5139f6 + that fix).

One thing I deliberately did NOT conclude

I read xmm0 at the breakpoint and the runtime's printer dumped what looks like the global object (PerformanceResourceTiming, crypto, navigator, a signal-exit emitter). I am not claiming that is the receiver. I broke on js_throw_type_error_not_a_function, which does not take the receiver in xmm0, so that value may well be a leftover register — the same over-reading that produced a wrong first-bad attribution on #11301. The correct next step is to break on js_native_call_method with the method name filtered to prompt and read its actual receiver argument. I have not done that yet.

If it does turn out to be the global object, this is a receiver-resolution bug rather than a missing-method bug, which would point somewhere quite different — worth establishing before anyone starts on a fix.

Related

Possibly the same family as #10893 (a static accessor reached through the class-id chain was invisible to the native-call tower) and #10848 (patching a built-in method), both of which were dispatch-tower gaps rather than missing implementations.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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