{"record":{"id":"e0611c6151934185","repo":"can1357/oh-my-pi","slug":"expression-is-required-for-evaluate","errorCode":null,"errorMessage":"expression is required for evaluate","messagePattern":"expression is required for evaluate","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/debug.ts","lineNumber":956,"sourceCode":"\t\t\t\tdetails.state = outcome.state;\n\t\t\t\tdetails.timedOut = outcome.timedOut;\n\t\t\t\treturn result.text(buildOutcomeText(outcome, timeoutSec, \"Step in\")).done();\n\t\t\t}\n\t\t\tcase \"step_out\": {\n\t\t\t\tconst outcome = await dapSessionManager.stepOut(combinedSignal, timeoutSec * 1000);\n\t\t\t\tdetails.snapshot = outcome.snapshot;\n\t\t\t\tdetails.state = outcome.state;\n\t\t\t\tdetails.timedOut = outcome.timedOut;\n\t\t\t\treturn result.text(buildOutcomeText(outcome, timeoutSec, \"Step out\")).done();\n\t\t\t}\n\t\t\tcase \"pause\": {\n\t\t\t\tconst snapshot = await dapSessionManager.pause(combinedSignal, timeoutSec * 1000);\n\t\t\t\tdetails.snapshot = snapshot;\n\t\t\t\treturn result.text(formatSessionSnapshot(snapshot).concat(\"Program paused.\").join(\"\\n\")).done();\n\t\t\t}\n\t\t\tcase \"evaluate\": {\n\t\t\t\tif (!params.expression) {\n\t\t\t\t\tthrow new ToolError(\"expression is required for evaluate\");\n\t\t\t\t}\n\t\t\t\tconst evaluationContext = (params.context as DapEvaluateArguments[\"context\"] | undefined) ?? \"repl\";\n\t\t\t\tconst response = await dapSessionManager.evaluate(\n\t\t\t\t\tparams.expression,\n\t\t\t\t\tevaluationContext,\n\t\t\t\t\tparams.frame_id,\n\t\t\t\t\tcombinedSignal,\n\t\t\t\t\ttimeoutSec * 1000,\n\t\t\t\t);\n\t\t\t\tdetails.snapshot = response.snapshot;\n\t\t\t\tdetails.evaluation = response.evaluation;\n\t\t\t\treturn result.text(formatEvaluation(response.evaluation)).done();\n\t\t\t}\n\t\t\tcase \"stack_trace\": {\n\t\t\t\tconst response = await dapSessionManager.stackTrace(params.levels, combinedSignal, timeoutSec * 1000);\n\t\t\t\tdetails.snapshot = response.snapshot;\n\t\t\t\tdetails.stackFrames = response.stackFrames;\n\t\t\t\treturn result.text(formatStackFrames(response.stackFrames)).done();","sourceCodeStart":938,"sourceCodeEnd":974,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/debug.ts#L938-L974","documentation":"The evaluate action throws this ToolError when params.expression is missing. Evaluating an expression in the paused debuggee requires the expression string; there is no implicit default. Unlike breakpoint actions there is no capability gate — the check runs unconditionally.","triggerScenarios":"Calling action=evaluate with params.expression undefined, empty string, or whitespace-only (falsy).","commonSituations":"Agent sends an empty evaluate to 'refresh' watches; expression field named wrong (e.g. expr/code); template interpolation produced an empty string at runtime.","solutions":["Provide the expression to evaluate, e.g. {expression: 'myVar.length', frame_id: 1}","Optionally set context ('repl', 'watch', 'hover', etc.) — it defaults to 'repl'","Guard empty interpolated expressions on the caller side before invoking the tool"],"exampleFix":"// before\nawait debugTool.run({ action: 'evaluate', expression: userInput }); // userInput was ''\n// after\nif (userInput.trim()) await debugTool.run({ action: 'evaluate', expression: userInput, frame_id: 1 });","handlingStrategy":"validation","validationCode":"if (typeof params.expression !== 'string' || params.expression.trim().length === 0) {\n  throw new Error('evaluate needs a non-empty expression');\n}","typeGuard":"function hasExpression(p) {\n  return typeof p === 'object' && p !== null\n    && typeof (p as { expression?: unknown }).expression === 'string'\n    && (p as { expression: string }).expression.trim().length > 0;\n}","tryCatchPattern":"try {\n  await debugTool.run({ action: 'evaluate', ...params });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes('expression is required')) {\n    // skip or prompt for a real expression instead of evaluating an empty one\n  } else throw err;\n}","preventionTips":["Interpolation of user/template input: check the result is non-empty before calling","Name the field exactly 'expression' per the tool schema","Provide frame_id from the paused state for correct scope resolution"],"tags":["debug","dap","parameter-validation","evaluate"],"backgroundTag":"missing-required-parameter","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}