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

  1. Confirm the script is non-empty, syntactically valid JavaScript/TypeScript and starts with valid program content (no stray shebang/BOM issues).
  2. Run `pnpm install` to reinstall dependencies — an acorn/parser version mismatch can return an unexpected AST shape.
  3. Reproduce with a minimal script; if a minimal valid script still fails, inspect the installed parser version against packages/codemode's lockfile.
  4. 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

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

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/308f8e7ce8592a4c. Report an issue: GitHub.