Topic Title: AI Agent Fails with "Received tool input did not match expected schema" on Complex Tool Call
* Your callin.io Version: 1.103.2 (Cloud)
* The Error: Received tool input did not match expected schema
* Summary of the Problem:
“The AI Agent fails to call a Code node tool that uses multiple parameters (including some of type JSON). The error occurs even when the prompt provides a direct command with hardcoded data that perfectly matches the tool’s schema. Simple, no-argument tools work, but the agent fails when it needs to construct the arguments for a more complex tool.”
`json
formatemailhtml
{
“nodes”: [
{
“parameters”: {
“chatModel”: “openai:gpt-4o”,
“prompt”: {
“__rl”: true,
“value”: “Your only task is to call thetool. You must use these exact, hardcoded values for the parameters:n-
weatherData : { "conditions": "test weather", "temperature": 75 }n-
todaysEvents : [{ "name": "Test a meeting" }]n-
upcomingEvents : <span class="chcklst-box fa fa-square-o fa-fw"></span>n-
recommendation : "This is a test of the formatting tool.",
weatherData
“mode”: “define”
}
},
“name”: “AI Agent”,
“type”: “callin.io/n8n-nodes-langchain.agent”,
“typeVersion”: 2.1,
“position”: [
1120,
360
],
“credentials”: {
“openAiApi”: {
“id”: “YOUR_CREDENTIAL_ID”,
“name”: “Your OpenAI Credential”
}
}
},
{
“parameters”: {
“toolName”: “format_email_html”,
“toolDescription”: “Formats the final email. It requires four parameters:(object),
todaysEvents (array),
upcomingEvents (array), and
recommendation (string).”,
“specifySchema”: true,
“schemaType”: “fixed”,
“parameters”: {
“parameters”: [
{
“name”: “weatherData”,
“type”: “json”,
“required”: true
},
{
“name”: “todaysEvents”,
“type”: “json”,
“required”: true
},
{
“name”: “upcomingEvents”,
“type”: “json”,
“required”: true
},
{
“name”: “recommendation”,
“type”: “string”,
“required”: true
}
]
},
“code”: “const weatherDataInput = weatherData || {};nconst todaysEventsInput = todaysEvents || <span class="chcklst-box fa fa-square-o fa-fw"></span>;nconst upcomingEventsInput = upcomingEvents || <span class="chcklst-box fa fa-square-o fa-fw"></span>;nconst recommendationInput = recommendation || ‘No specific recommendation provided.’;nnconst htmlEmailBody =
Test Report
Weather
${weatherDataInput.conditions || 'N/A'}
Today's Events
${todaysEventsInput.length > 0 ? todaysEventsInput[0].name : 'N/A'}
Recommendation
${recommendationInput}
``;nnreturn { string: htmlEmailBody };”
},
“name”: “formatemailhtml”,
“type”: “callin.io-nodes-base.code”,
“typeVersion”: 2,
“position”: [
900,
360
]
}
],
“connections”: {
“formatemailhtml”: {
“main”: [
[
{
“node”: “AI Agent”,
“type”: “main”,
“index”: 0
}
]
]
}
}
}
```
Hello! Hope you're doing well. Welcome.
What steps are needed for the given workflow to cause it to fail?
Thanks for the response. This is my initial attempt at building something, and I was working with Gemini Pro until it indicated it could no longer assist. The plan is straightforward: a daily trigger, retrieve today's calendar events, the next five days' calendar events, the weather for my town, and the air quality index (Utah experiences inversions). Finally, output a well-formatted email. Here's the AI prompt, simplified to focus on the core task: Your sole responsibility is to invoke the format_email_html
tool. You must use these precise, hardcoded values for the parameters:
weatherData
: { “conditions”: “test weather”, “temperature”: 75 }todaysEvents
: [ { “name”: “Test a meeting” } ]upcomingEvents
:recommendation
: “This is a test of the formatting tool.”.
Here is the email formatting that fails to align with the schema: // These variables are now passed directly as named parameters from the agent.
const weatherDataInput = weatherData || {};
const todaysEventsInput = todaysEvents || ;
const upcomingEventsInput = upcomingEvents || ;
const recommendationInput = recommendation || ‘No specific recommendation provided.’;
// Function to format event details
const formatEvent = (event) => {
const name = event.name || ‘N/A’;
const date = event.date || ‘N/A’;
const timeStart = event.timeStart || ‘’;
const timeEnd = event.timeEnd ? to ${event.timeEnd}
: ‘’;
const platform = event.platform ? (${event.platform})
: ‘’;
return <li><strong>${name}</strong><br>When: ${date} ${timeStart}${timeEnd}${platform}</li>
;
};
// Build the HTML for today’s events
let todaysEventsHtml = ‘’;
if (todaysEventsInput.length > 0) {
todaysEventsHtml = todaysEventsInput.map(formatEvent).join(‘’);
} else {
todaysEventsHtml = ‘
’;
}
// Build the HTML for upcoming events
let upcomingEventsHtml = ‘’;
if (upcomingEventsInput.length > 0) {
upcomingEventsHtml = upcomingEventsInput.map(formatEvent).join(‘’);
} else {
upcomingEventsHtml = ‘
’;
}
// Construct the full HTML string
const htmlEmailBody =
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333333; margin: 0; padding: 0; background-color: #f4f4f4; }
.email-container { max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #dddddd; border-radius: 8px; background-color: #ffffff; }
h2 { color: #2c3e50; margin-top: 0; }
h3 { color: #34495e; border-bottom: 1px solid #eeeeee; padding-bottom: 10px; }
ul { list-style-type: none; padding: 0; }
ul li { background-color: #f8f9fa; margin-bottom: 10px; padding: 10px; border-left: 3px solid #3498db; }
.recommendation { background-color: #ecf0f1; padding: 15px; border-left: 5px solid #1abc9c; margin-top: 20px; border-radius: 4px; }
.footer { margin-top: 30px; font-size: 0.9em; text-align: center; color: #7f8c8d; }
Your Daily Update
Weather & Air Quality
- Weather: ${weatherDataInput.conditions || 'N/A'} at ${weatherDataInput.temperature || 'N/A'}°F (feels like ${weatherDataInput.feelsLike || 'N/A'}°F)
- Air Quality: ${(weatherDataInput.airQuality && weatherDataInput.airQuality.status) || 'N/A'} (AQI: ${(weatherDataInput.airQuality && weatherDataInput.airQuality.ozone) || 'N/A'})
Today's Events
${todaysEventsHtml}
Upcoming Events
${upcomingEventsHtml}
💡 Recommendation
${recommendationInput}
`;
// Return the final HTML in the correct object format for the agent
return { string: htmlEmailBody };
Let me know if you need further assistance!
Thanks.