different-ai/openwork · error · InterpreterRuntimeError
Failed to parse script as a Program node.
Error message
Failed to parse script as a Program node.
What it means
After TypeScript transpilation, parseProgram falls back to an acorn-style parser (with allowReturnOutsideFunction/allowAwaitOutsideFunction) and validates that the result is a record with type "Program" and an array body. If the parser returns anything else — an unexpected parser failure, a non-Program result, or a shape the library doesn't recognize — it throws this generic InterpreterRuntimeError. It means the script could not be converted into the ProgramNode the interpreter walks.
Source
Thrown at packages/codemode/src/interpreter/runtime.ts:146
`Failed to parse TypeScript: ${flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`,
undefined,
"ParseError",
)
}
const bodyStart = transpiled.outputText.indexOf("{") + 1
const bodyEnd = transpiled.outputText.lastIndexOf("}")
const executableCode = transpiled.outputText.slice(bodyStart, bodyEnd)
const parsed = parse(executableCode, {
ecmaVersion: "latest",
sourceType: "script",
allowReturnOutsideFunction: true,
allowAwaitOutsideFunction: true,
locations: true,
}) as unknown
if (!isRecord(parsed) || parsed.type !== "Program" || !Array.isArray(parsed.body)) {
throw new InterpreterRuntimeError("Failed to parse script as a Program node.")
}
return parsed as ProgramNode
}
const publicErrorMessage = (message: string): string =>
message.replace(/\/(?:Users|home|private|tmp|var\/folders)\/[^\s"'`]+/g, "<redacted-path>")
const normalizeError = (error: unknown): Diagnostic => {
if (error instanceof InterpreterRuntimeError) {
return {
kind: error.kind,
message: `${error.message}${formatLocation(error.node)}`,
...(error.node?.loc ? { location: sourceLocation(error.node) } : {}),
...(error.suggestions ? { suggestions: error.suggestions } : {}),
}
}
View on GitHub (pinned to 2b7df46e8a)
Solutions
- Confirm the script is non-empty, syntactically valid JavaScript/TypeScript and starts with valid program content (no stray shebang/BOM issues).
- Run `pnpm install` to reinstall dependencies — an acorn/parser version mismatch can return an unexpected AST shape.
- Reproduce with a minimal script; if a minimal valid script still fails, inspect the installed parser version against packages/codemode's lockfile.
- Catch the InterpreterRuntimeError and log the raw script for debugging when parsing third-party/user code.
Example fix
// before
await run("")
// after
await run("return 1") Defensive patterns
Strategy: validation
Validate before calling
export const scriptLooksLikeProgram = (script: string): boolean => {
if (typeof script !== "string" || script.trim().length === 0) return false
// must at least tokenize; deep validation happens via program()
return !/^[\uFEFF]/.test(script)
} Type guard
const isProgramNode = (v: unknown): v is { type: "Program"; body: unknown[] } =>
typeof v === "object" && v !== null && (v as { type?: unknown }).type === "Program" && Array.isArray((v as { body?: unknown }).body) Try / catch
try {
await program(script)
} catch (e) {
if (e instanceof Error && e.message === "Failed to parse script as a Program node.") {
// reinstall/review parser dependency; log script for minimal repro
} else throw e
} Prevention
- Reject empty/whitespace-only scripts before calling the runtime.
- Run `pnpm install` after dependency changes so the parser module matches the lockfile.
- Test the runtime with a minimal known-good script when upgrading codemode.
- Avoid shimming/monkey-patching the parser package.
When it happens
Trigger: Feeding the runtime a script that the fallback parser either fails to parse into a Program (syntax it can't accept at top level) or returns a malformed result for; also occurs if the parser module is replaced/shimmed and returns a non-standard object.
Common situations: Scripts with top-level constructs incompatible with the parser options, empty or whitespace-only script strings, monkey-patched parser dependencies after a bad install/dependency hoisting, or very old/new parser versions returning a different AST shape.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Expected '${key}' to be a boolean.
- Invalid AST node while reading ${context}.
- Expected '${key}' to be an array.
- Expected '${key}' to be a string.
- String.${name} expects argument ${index + 1} to be a number.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/308f8e7ce8592a4c.
Report an issue: GitHub.