vercel/ai · error · InvalidToolInputError

Invalid input for tool ${toolName}: ${getErrorMessage(cause)

Error message

Invalid input for tool ${toolName}: ${getErrorMessage(cause)}

What it means

InvalidToolInputError thrown when parsing a provider-executed dynamic tool call's `input` string with safeParseJSON fails — the model produced text that is not valid JSON. The SDK requires tool input to be JSON so it can type-check and forward arguments.

Source

Thrown at packages/ai/src/generate-text/parse-tool-call.ts:146

    return toolCall;
  }

  return {
    ...toolCall,
    input: await refine(toolCall.input as InferToolInput<TOOLS[keyof TOOLS]>),
  } as TypedToolCall<TOOLS>;
}

async function parseProviderExecutedDynamicToolCall(
  toolCall: LanguageModelV4ToolCall,
): Promise<DynamicToolCall> {
  const parseResult =
    toolCall.input.trim() === ''
      ? { success: true as const, value: {} }
      : await safeParseJSON({ text: toolCall.input });

  if (parseResult.success === false) {
    throw new InvalidToolInputError({
      toolName: toolCall.toolName,
      toolInput: toolCall.input,
      cause: parseResult.error,
    });
  }

  return {
    type: 'tool-call',
    toolCallId: toolCall.toolCallId,
    toolName: toolCall.toolName,
    input: parseResult.value,
    providerExecuted: true,
    dynamic: true,
    providerMetadata: toolCall.providerMetadata,
  };
}

async function doParseToolCall<TOOLS extends ToolSet>({

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Check `error.cause` / `toolInput` to see the malformed JSON and increase maxOutputTokens if truncated.
  2. Add `experimental_repairToolCall` to fix common malformations automatically.
  3. Ask the model to output raw JSON only (prompt) or switch to a model with stricter tool-call JSON support.
  4. Catch InvalidToolInputError (isInstance) and re-prompt the model for that step.

Example fix

// before
await generateText({ model, prompt, tools, experimental_repairToolCall: undefined });
// after
await generateText({
  model,
  prompt,
  tools,
  experimental_repairToolCall: repairToolCall, // fixes malformed JSON inputs
});
Defensive patterns

Strategy: try-catch

Type guard

function isInvalidToolInput(e: unknown): e is InvalidToolInputError {
  return InvalidToolInputError.isInstance(e);
}

Try / catch

try {
  await generateText({ model, prompt, tools });
} catch (e) {
  if (InvalidToolInputError.isInstance(e)) {
    console.warn('malformed tool JSON:', e.toolInput, e.cause);
    // retry with feedback or enable experimental_repairToolCall
  } else throw e;
}

Prevention

When it happens

Trigger: A provider-executed dynamic tool call whose `input` is non-empty but malformed JSON (truncated output, markdown fences, trailing text).

Common situations: Small maxOutputTokens cutting JSON mid-stream; models emitting comments or ```json fences; provider quirk after version upgrade; streaming interruption.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/29cd18ec4bef8795. Report an issue: GitHub.