{"record":{"id":"e5a9fdfcce1cc78e","repo":"can1357/oh-my-pi","slug":"eval-tool-requires-a-session-when-not-using-proxy","errorCode":null,"errorMessage":"Eval tool requires a session when not using proxy executor","messagePattern":"Eval tool requires a session when not using proxy executor","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/eval.ts","lineNumber":462,"sourceCode":"\t\tprivate readonly session: ToolSession | null,\n\t\toptions?: EvalToolOptions,\n\t) {\n\t\tthis.#proxyExecutor = options?.proxyExecutor;\n\t}\n\n\tasync execute(\n\t\t_toolCallId: string,\n\t\tparams: typeof evalSchema.infer,\n\t\tsignal?: AbortSignal,\n\t\tonUpdate?: AgentToolUpdateCallback,\n\t\tctx?: AgentToolContext,\n\t): Promise<AgentToolResult<EvalToolDetails | undefined>> {\n\t\tif (this.#proxyExecutor) {\n\t\t\treturn this.#proxyExecutor(params, signal);\n\t\t}\n\n\t\tif (!this.session) {\n\t\t\tthrow new ToolError(\"Eval tool requires a session when not using proxy executor\");\n\t\t}\n\t\tconst session = this.session;\n\t\tconst excludeWebP = webpExclusionForModel(session.getActiveModel?.());\n\n\t\tconst cellLanguage: EvalLanguage =\n\t\t\tparams.language === \"py\"\n\t\t\t\t? \"python\"\n\t\t\t\t: params.language === \"rb\"\n\t\t\t\t\t? \"ruby\"\n\t\t\t\t\t: params.language === \"jl\"\n\t\t\t\t\t\t? \"julia\"\n\t\t\t\t\t\t: \"js\";\n\t\t// Bound backend discovery by the eval cell's own timeout and abort signal:\n\t\t// the cell IdleTimeout is armed only later in #runCells, so a hung runtime\n\t\t// probe would otherwise wedge the whole turn (issue #9466).\n\t\tconst cellTimeoutMs =\n\t\t\tparams.timeout === 0\n\t\t\t\t? 0","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/eval.ts#L444-L480","documentation":"EvalTool can be constructed with session = null when it is backed by a proxyExecutor (e.g. remote/bridge transports). execute() first delegates to the proxy executor; if no proxy executor is wired AND the session is null, there is no way to run the cell, so it throws. This is an internal wiring/invariant error, not a user-input problem.","triggerScenarios":"Instantiating `new EvalTool(null)` without passing { proxyExecutor } in options and then calling execute(); or calling execute on a proxy-mode EvalTool instance where the proxyExecutor was not supplied.","commonSituations":"Embedding the coding-agent SDK and constructing tools manually without a ToolSession; test harnesses building EvalTool with null session and forgetting the proxyExecutor option; version changes where the proxy executor wiring moved.","solutions":["Pass a valid ToolSession to the EvalTool constructor.","Alternatively supply an explicit proxyExecutor: new EvalTool(null, { proxyExecutor }).","If using the SDK's tool factory, use createTools()/the standard registry rather than hand-constructing EvalTool."],"exampleFix":"// before\nconst tool = new EvalTool(null);\n// after\nconst tool = new EvalTool(session);\n// or\nconst tool = new EvalTool(null, { proxyExecutor: myProxy });","handlingStrategy":"validation","validationCode":"if (!session && !options?.proxyExecutor) {\n  throw new Error(\"EvalTool needs a session or a proxyExecutor\");\n}\nconst tool = new EvalTool(session, options);","typeGuard":"function isUsableEvalTool(t: EvalTool): boolean { return t[\"session\"] !== null; } // or expose an isProxy/hasSession accessor","tryCatchPattern":"try {\n  await evalTool.execute(id, params, signal);\n} catch (e) {\n  if (e instanceof ToolError && e.message.includes(\"requires a session\")) {\n    // re-create the tool with a session or proxy executor, then retry once\n  } else throw e;\n}","preventionTips":["Never construct EvalTool(null) without { proxyExecutor }.","Prefer the standard createTools()/registry path over manual tool construction.","Add a constructor-time assert or unit test that proxy-mode tools expose execute safely."],"tags":["initialization","eval-tool","wiring","sdk"],"backgroundTag":"missing-dependency-not-initialized","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}