{"record":{"id":"7417caf243a9cb04","repo":"vercel/ai","slug":"error-repairing-tool-call-geterrormessage-cause","errorCode":null,"errorMessage":"Error repairing tool call: ${getErrorMessage(cause)}","messagePattern":"Error repairing tool call: (.+?)","errorType":"exception","errorClass":"ToolCallRepairError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/generate-text/parse-tool-call.ts","lineNumber":79,"sourceCode":"      }\n\n      let repairedToolCall: LanguageModelV4ToolCall | null = null;\n\n      try {\n        repairedToolCall = await repairToolCall({\n          toolCall,\n          tools,\n          inputSchema: async ({ toolName }) => {\n            const inputSchema = getOwn(tools, toolName)?.inputSchema;\n            return await asSchema(inputSchema).jsonSchema;\n          },\n          instructions,\n          system: instructions,\n          messages,\n          error,\n        });\n      } catch (repairError) {\n        throw new ToolCallRepairError({\n          cause: repairError,\n          originalError: error,\n        });\n      }\n\n      // no repaired tool call returned\n      if (repairedToolCall == null) {\n        throw error;\n      }\n\n      return await refineParsedToolCallInput({\n        toolCall: await doParseToolCall({ toolCall: repairedToolCall, tools }),\n        refineToolInput,\n      });\n    }\n  } catch (error) {\n    // use parsed input when possible\n    const parsedInput = await safeParseJSON({ text: toolCall.input });","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/ai/src/generate-text/parse-tool-call.ts#L61-L97","documentation":"ToolCallRepairError wraps a failure that happened inside `experimental_repairToolCall` while trying to fix a broken tool call (e.g. malformed JSON). The original parse error is preserved as `originalError` and the repair failure as `cause`. It signals the repair path itself threw, not the original defect.","triggerScenarios":"Providing `experimental_repairToolCall` to generateText/streamText and the repair function (often itself an LLM call) throws — network failure, API error, or a bug inside the repair callback.","commonSituations":"Repair prompt calling a model with invalid/missing API key; repair function throwing on unexpected input; timeout inside the repair LLM call; passing an async repair that rejects.","solutions":["Inspect `error.cause` for the real reason the repair function failed and fix that (API key, model availability, prompt).","Make the repair function defensive: wrap its body in try/catch and return the original tool call or null instead of throwing.","Validate that the model used for repair supports tool calling and is correctly configured."],"exampleFix":"// before\nexperimental_repairToolCall: async ({ toolCall, error }) => {\n  const fixed = await repairModel(toolCall); // may throw\n  return fixed;\n}\n// after\nexperimental_repairToolCall: async ({ toolCall, error }) => {\n  try {\n    return await repairModel(toolCall);\n  } catch (e) {\n    return null; // give up gracefully instead of throwing\n  }\n}","handlingStrategy":"try-catch","validationCode":"if (experimental_repairToolCall && typeof experimental_repairToolCall !== 'function') {\n  throw new Error('experimental_repairToolCall must be a function');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await generateText({ model, prompt, tools, experimental_repairToolCall });\n} catch (e) {\n  if (ToolCallRepairError.isInstance(e)) {\n    console.error('repair failed:', e.cause, 'original:', e.originalError);\n    // fall back to an un-repaired retry or surface a friendly message\n  } else throw e;\n}","preventionTips":["Wrap the body of your repair function in try/catch and return null on failure.","Ensure the repair model has a valid API key and tool-calling support.","Log e.cause to identify the underlying repair failure quickly."],"tags":["tool-calling","repair","wrapped-error"],"backgroundTag":"tool-call-repair-failed","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}