{"record":{"id":"9e6ebc321689d76e","repo":"mastra-ai/mastra","slug":"run-id-is-required","errorCode":null,"errorMessage":"Run id is required","messagePattern":"Run id is required","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"packages/server/src/server/handlers/agents.ts","lineNumber":2529,"sourceCode":"  responseType: 'stream' as const,\n  streamFormat: 'sse' as const,\n  pathParamSchema: agentIdPathParams,\n  bodySchema: approveToolCallBodySchema,\n  responseSchema: toolCallResponseSchema,\n  summary: 'Approve tool call',\n  description: 'Approves a pending tool call and continues agent execution',\n  tags: ['Agents', 'Tools'],\n  requiresAuth: true,\n  handler: async ({ mastra, agentId, abortSignal, requestContext, ...params }) => {\n    try {\n      const agent = await getAgentFromSystem({\n        mastra,\n        agentId,\n        versionOptions: extractVersionOptions(requestContext),\n      });\n\n      if (!params.runId) {\n        throw new HTTPException(400, { message: 'Run id is required' });\n      }\n\n      if (!params.toolCallId) {\n        throw new HTTPException(400, { message: 'Tool call id is required' });\n      }\n\n      // UI Frameworks may send \"client tools\" in the body,\n      // but it interferes with llm providers tool handling, so we remove them\n      sanitizeBody(params, ['tools', 'actor']);\n\n      await validateDurableToolCallAccess({\n        mastra,\n        agent,\n        runId: params.runId,\n        toolCallId: params.toolCallId,\n        requestContext,\n      });\n","sourceCodeStart":2511,"sourceCodeEnd":2547,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/agents.ts#L2511-L2547","documentation":"The tool-approval/approval-result style endpoint operates on a specific run and tool call, so params.runId must be present. The handler throws HTTP 400 'Run id is required' before even checking toolCallId. The runId ties the response to the suspended run awaiting approval.","triggerScenarios":"POSTing a tool call approval/continue response without runId in the request body/params.","commonSituations":"Client reconstructing the resume request from a webhook payload missing the run ID; runId stored under a different key in the client's suspended-run state; restarting the client process and losing the active run reference.","solutions":["Include runId in the request body (taken from the suspended-run/watch event)","Persist the runId alongside toolCallId when the run suspends so it survives restarts","Check field naming matches the API schema (runId, camelCase)"],"exampleFix":"// before\nawait client.getAgent('a').approveToolCall({ toolCallId: 'call_1' });\n// after\nawait client.getAgent('a').approveToolCall({ runId: 'run_abc', toolCallId: 'call_1' });","handlingStrategy":"validation","validationCode":"function assertApprovalPayload(p: { runId?: string; toolCallId?: string }) {\n  if (!p.runId) throw new Error('Run id is required');\n  if (!p.toolCallId) throw new Error('Tool call id is required');\n}","typeGuard":"function hasApprovalIds(p: { runId?: string; toolCallId?: string }): p is { runId: string; toolCallId: string } {\n  return typeof p.runId === 'string' && p.runId.length > 0 && typeof p.toolCallId === 'string' && p.toolCallId.length > 0;\n}","tryCatchPattern":"try {\n  await respondToToolCall(payload);\n} catch (e) {\n  if (e?.status === 400 && /Run id is required/.test(e.message)) {\n    console.error('Suspended-run state lost runId; recover from the stored suspension record');\n  }\n  throw e;\n}","preventionTips":["Persist runId and toolCallId together whenever a run suspends on a tool call","Take both IDs from the same suspension event, never reconstruct partially","Type the approval request so runId is required at compile time"],"tags":["http-400","missing-parameter","tool-approval","server"],"backgroundTag":"missing-required-parameter","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}