Custom tools troubleshooting

Overview

Troubleshoot and fix common issues with custom tool integrations in your Vapi assistants.

In this guide, you’ll learn to:

  • Diagnose why tools aren’t triggering
  • Fix response format errors
  • Resolve parameter and token issues
  • Handle multiple tool scenarios

Quick diagnosis

Start with the most common issue for your symptoms:

Tool won’t trigger

Your assistant doesn’t call the tool even when it should.

Check your assistant prompting

Use the exact tool name in your assistant instructions. If your tool is named get_weather, reference get_weather in prompts, not weather_tool.

Verify required parameters

Check that your tool schema includes all required parameters:

Tool schema
1{
2 "name": "get_weather",
3 "parameters": {
4 "type": "object",
5 "properties": {
6 "city": {
7 "type": "string",
8 "description": "City name for weather lookup"
9 }
10 },
11 "required": ["city"] // Must be array of required parameter names
12 }
13}

Enable schema validation

Add strict: true to catch validation errors early:

Tool configuration
1{
2 "name": "get_weather",
3 "description": "Get current weather for a city",
4 "parameters": {
5 // ... your parameters
6 },
7 "strict": true,
8 "maxTokens": 500
9}

Check your call logs for “Schema validation errors” to identify parameter issues.

No result returned error

Logs show “ok, no result returned” or similar messages.

Use the correct response format

Your webhook must return this exact JSON structure:

1{
2 "results": [
3 {
4 "toolCallId": "call_123",
5 "result": "Your response as single-line string"
6 }
7 ]
8}

Common format mistakes

Always return HTTP 200, even for errors. Any other status code is ignored completely.

1// Return this with HTTP 200
2{
3 "results": [
4 {
5 "toolCallId": "call_123",
6 "error": "Something went wrong"
7 }
8 ]
9}

Use single-line strings only. Line breaks cause parsing errors.

❌ Has line breaks
1{
2 "result": "Line 1\nLine 2\nLine 3"
3}
✅ Single line
1{
2 "result": "Line 1, Line 2, Line 3"
3}

The response must have the results array structure. Individual result objects won’t work.

The toolCallId in your response must exactly match the ID from the request.

Both result and error fields must be strings, not objects or arrays.

Response ignored

Tool returns data but the assistant doesn’t use it in conversation.

Fix line breaks and formatting

1{
2 "results": [
3 {
4 "toolCallId": "call_123",
5 "result": "Temperature: 72°F\nCondition: Sunny\nHumidity: 45%"
6 }
7 ]
8}

Verify HTTP status and JSON structure

1

Check HTTP status

Ensure your webhook returns HTTP 200. Any other status code causes the response to be ignored.

3

Validate JSON format

Use a JSON validator to ensure your response structure is valid.

4

Match tool call IDs

For multiple tools, return results in the same order as calls were triggered, with matching toolCallId values.

Token truncation

Tool parameters or responses are getting cut off.

Increase token limits

The default token limit is only 100. Increase it for complex tools:

Tool configuration
1{
2 "name": "complex_tool",
3 "description": "Tool that needs more tokens",
4 "parameters": {
5 // ... your parameters
6 },
7 "maxTokens": 500 // Increase from default 100
8}

Look for “Token truncation warnings” in your call logs to identify when this occurs.

Multiple tools scenarios

Some tools in parallel calls fail or return wrong results.

Handle multiple tool responses

Return all results in the same order as the calls were triggered:

Multiple tool response
1{
2 "results": [
3 {
4 "toolCallId": "call_1",
5 "result": "First tool success"
6 },
7 {
8 "toolCallId": "call_2",
9 "error": "Second tool failed"
10 },
11 {
12 "toolCallId": "call_3",
13 "result": "Third tool success"
14 }
15 ]
16}

Use HTTP 200 for the entire response, even if some individual tools error. Handle errors within the results array using the error field.

Async vs sync behavior

Tool behavior doesn’t match your expectations.

Most tools should use sync behavior unless you specifically need async processing for long-running operations.

Reference: Required formats

Response format template

1{
2 "results": [
3 {
4 "toolCallId": "call_123",
5 "result": "Single-line string response"
6 }
7 ]
8}

Tool schema template

Complete tool configuration
1{
2 "name": "tool_name",
3 "description": "Clear description of what the tool does",
4 "parameters": {
5 "type": "object",
6 "properties": {
7 "param1": {
8 "type": "string",
9 "description": "Parameter description"
10 }
11 },
12 "required": ["param1"]
13 },
14 "strict": true,
15 "maxTokens": 500,
16 "async": false
17}

Critical response rules

Always return HTTP 200 - Even for errors
Use single-line strings - No \n line breaks
Match tool call IDs exactly - From request to response
Include results array - Required structure
String types only - For result/error values

Debugging with call logs

Look for these key error messages in your call logs:

Error MessageWhat It MeansHow to Fix
”ok, no result returned”Wrong response formatUse correct JSON structure
”Tool call ID mismatches”toolCallId doesn’t matchEnsure exact ID match
”HTTP errors”Webhook not returning 200Return HTTP 200 always
”Schema validation errors”Missing required parametersCheck required array
”Token truncation warnings”Need more tokensIncrease maxTokens
”Response parsing errors”Malformed JSON/line breaksFix JSON format