{"record":{"id":"308f8e7ce8592a4c","repo":"different-ai/openwork","slug":"failed-to-parse-script-as-a-program-node","errorCode":null,"errorMessage":"Failed to parse script as a Program node.","messagePattern":"Failed to parse script as a Program node\\.","errorType":"exception","errorClass":"InterpreterRuntimeError","httpStatus":null,"severity":"error","filePath":"packages/codemode/src/interpreter/runtime.ts","lineNumber":146,"sourceCode":"      `Failed to parse TypeScript: ${flattenDiagnosticMessageText(diagnostic.messageText, \"\\n\")}`,\n      undefined,\n      \"ParseError\",\n    )\n  }\n\n  const bodyStart = transpiled.outputText.indexOf(\"{\") + 1\n  const bodyEnd = transpiled.outputText.lastIndexOf(\"}\")\n  const executableCode = transpiled.outputText.slice(bodyStart, bodyEnd)\n  const parsed = parse(executableCode, {\n    ecmaVersion: \"latest\",\n    sourceType: \"script\",\n    allowReturnOutsideFunction: true,\n    allowAwaitOutsideFunction: true,\n    locations: true,\n  }) as unknown\n\n  if (!isRecord(parsed) || parsed.type !== \"Program\" || !Array.isArray(parsed.body)) {\n    throw new InterpreterRuntimeError(\"Failed to parse script as a Program node.\")\n  }\n\n  return parsed as ProgramNode\n}\n\nconst publicErrorMessage = (message: string): string =>\n  message.replace(/\\/(?:Users|home|private|tmp|var\\/folders)\\/[^\\s\"'`]+/g, \"<redacted-path>\")\n\nconst normalizeError = (error: unknown): Diagnostic => {\n  if (error instanceof InterpreterRuntimeError) {\n    return {\n      kind: error.kind,\n      message: `${error.message}${formatLocation(error.node)}`,\n      ...(error.node?.loc ? { location: sourceLocation(error.node) } : {}),\n      ...(error.suggestions ? { suggestions: error.suggestions } : {}),\n    }\n  }\n","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/packages/codemode/src/interpreter/runtime.ts#L128-L164","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait run(\"\")\n// after\nawait run(\"return 1\")","handlingStrategy":"validation","validationCode":"export const scriptLooksLikeProgram = (script: string): boolean => {\n  if (typeof script !== \"string\" || script.trim().length === 0) return false\n  // must at least tokenize; deep validation happens via program()\n  return !/^[\\uFEFF]/.test(script)\n}","typeGuard":"const isProgramNode = (v: unknown): v is { type: \"Program\"; body: unknown[] } =>\n  typeof v === \"object\" && v !== null && (v as { type?: unknown }).type === \"Program\" && Array.isArray((v as { body?: unknown }).body)","tryCatchPattern":"try {\n  await program(script)\n} catch (e) {\n  if (e instanceof Error && e.message === \"Failed to parse script as a Program node.\") {\n    // reinstall/review parser dependency; log script for minimal repro\n  } else throw e\n}","preventionTips":["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."],"tags":["parse-error","ast","interpreter","codemode"],"backgroundTag":"parse-to-program-failed","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}