You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
new Worker(file) is only compiled into a native worker entry when the compile-time worker-path helper (crates/perry-hir/src/dynamic_import/worker_paths.rs) can evaluate file. It accepts string literals, new URL(x, import.meta.url), path joins, ternaries and calls to synchronous single-return helpers, and rejects everything else: async and generator helpers are not static path helpers, helper body must contain only a single return (no effects, mutation or multiple returns), and Expr::Await falls into unsupported expression (effects, mutation and opaque calls are not evaluated). The runtime then throws worker_threads Worker filename was not statically resolvable at compile time; constructing this Worker is unsupported in the compiled binary.
OpenCode v1.18.30 (tracker #10107) picks its TUI worker like this (packages/opencode/src/cli/cmd/tui.ts), with OPENCODE_WORKER_PATH supplied as a --define string by scripts/build_opencode.ts:
The full compile warns worker_threads Worker in module cli/cmd/tui.ts: Worker path helper: unsupported expression (effects, mutation and opaque calls are not evaluated) — this Worker will throw if constructed at runtime, and opencode (the TUI, the default command) dies right after startup with the runtime error above. Every other rung is fine.
Ask
Extend the helper so this shape resolves, without evaluating effects:
await <expr> → resolve <expr> (an await does not change which paths are possible).
A helper (sync or async) whose body is a chain of if (<cond>) return <e_i>; / const x = <pure expr>; statements ending in return <e_n>; resolves to the union of all return expressions' paths; conditions are not evaluated (an opaque call like await Filesystem.exists(...) inside a condition is fine because the value is still one of the returns). Union semantics are sound for this purpose: extra candidates only cost an extra compiled worker entry.
With a --define, typeof OPENCODE_WORKER_PATH !== "undefined" is a constant; folding it is optional once (2) uses union semantics.
A candidate that resolves to a file that does not exist at compile time (here ./cli/tui/worker.js, the bun-build layout) should be skipped with a warning rather than failing the whole resolution; duplicates (OPENCODE_WORKER_PATH and ../tui/worker.ts name the same file) collapse to one entry.
Keep the current limits (work budget, string limit, recursion guard) and the current rejections for real effects (assignments, calls whose result is returned from an opaque callee).
Expected: opencode (TUI) constructs its worker natively; perry compile reports the worker entry in its summary instead of the warning.
Activity
proggeramlug commentedon Sep 14, 2026
PR: #10239 — resolves awaited helpers and if/return unions, skips missing candidates, and dispatches native worker entries. Linux regression suites passed; the focused OpenCode TUI check discovers src/cli/tui/worker.ts without the unsupported-helper warning. Refs #10107.
fix: resolve awaited worker path helpers (#10236)
proggeramlug commentedon Sep 14, 2026
Fixed by merge train 186r (#10247) at eb13fa1.