AI Agent → Call Workflow Tool → Input parameters do not arrive in the sub-workflow trigger node (“When Executed by Another Workflow”)

Describe the problem/error/question

I’m using an AI Agent in a Main workflow to collect appointment preferences from users.
The agent then uses the Call n8n Workflow Tool to trigger a sub-workflow which should receive parameters such as weekday or startAfter.

These values are visible in the input of the Call Workflow Tool, but in the sub-workflow execution, the When Executed by Another Workflow node always receives an empty item {}, so the logic falls back to default slots.

I tried multiple configurations for both the Call tool and the trigger (Accept all data / Define using JSON example / Define using fields below), changed field types, and modified the Agent prompt.
In some configurations, the Agent even stops using the tool completely.

I’m trying to find out how to properly pass structured input from the AI Agent → Call Workflow Tool → sub-workflow trigger.

What is the error message (if any)?

No error displayed — the output item is always empty

Please share your workflow

(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

Hi @botimy please can you share your workflow in a code block so we can have a look at what could be the problem. In most cases it is either a miss config or you need a more explicit prompt.

Thanks for your reply!

Because of the new-user link limit I cannot paste the full workflow with all nodes and URLs, so I’m sharing a minimal version that still shows the AI Agent setup, the Call Workflow Tool configuration, and the called “Terminfinder” sub-workflow.

Here is a reduced version of my Main workflow with just the AI Agent and the “Call Terminfinder” tool:

{
“nodes”: [
{
“id”: “930c1e83-98cd-4ef6-b16f-290341be57a3”,
“name”: “OpenAI Chat Model1”,
“type”: “@n8n/n8n-nodes-langchain.lmChatOpenAi”,
“typeVersion”: 1.2,
“position”: [112, 1792],
“parameters”: {
“model”: {
“_rl": true,
“value”: “gpt-4o”,
“mode”: “list”,
“cachedResultName”: “gpt-4o”
},
“options”: {}
}
},
{
“id”: “6fdf4b1b-4b8c-4482-80ae-37d5f7a2c701”,
“name”: “Simple Memory1”,
“type”: “@n8n/n8n-nodes-langchain.memoryBufferWindow”,
“typeVersion”: 1.3,
“position”: [256, 1792],
“parameters”: {
“sessionIdType”: “customKey”,
“sessionKey”: "={{ 'cid
’ + $json.body.conversation.messages[0].conversation_id }}”,
“contextWindowLength”: 20
}
},
{
“id”: “ab957af6-965e-4a13-8ab2-b8432e90f2f5”,
“name”: “AI Agent1”,
“type”: “@n8n/n8n-nodes-langchain.agent”,
“typeVersion”: 2.2,
“position”: [496, 1472],
“onError”: “continueRegularOutput”,
“parameters”: {
“promptType”: “define”,
“text”: “={{ \n $json.body?.processed_message_content \n ?? $json.body?.content \n ?? $json.messages?.[0]?.content \n ?? $json.content \n ?? $json.text \n ?? $json.message \n ?? $json.transcription \n ?? ‘Hallo’\n}}\n”,
“options”: {
“systemMessage”: “=You are a helpful AI assistant.\n\n# Tools you can use\n\n1) Google Calendar\n - Read (get events)\n - Create (create event)\n - Delete (delete event)\n\n2) Google Sheets\n - Add Row\n - Update Row\n - Read\n\n3) Gmail\n - Send confirmation email to the user\n\n4) Terminfinder (Call n8n Workflow Tool)\n - Returns up to 5 truly free 60-minute time slots.\n - You never calculate appointment slots yourself.\n - Every time you call this tool, you send a JSON object as input.\n - Allowed top-level fields:\n - startAfter (ISO datetime string with offset)\n - weekday (1=Mon … 5=Fri)\n - If you don’t need any filter, send an empty object {}.\n - Never send these fields if they do not clearly follow from the user’s request.\n - Do not use a “query” object and do not send any other fields.\n - If an error happens when calling the tool: adjust the parameters and call the tool again before you reply.\n\nThe current date and time is German time: {{ $now }}.\n\n—\n\n# Conversation flow\n\nStart with:\n"How can I help you? Would you like to book an appointment?"\n\nIf the user says yes, ask for these in this order:\n1. Email address\n2. Name\n3. Phone number\n4. Location / time zone\n5. Reason for the appointment\n\nAlways ask only 1 question per message.\n\nAfter each piece of information, immediately save it to Google Sheets.\n\n—\n\n# Appointment finding (always via the Terminfinder tool)\n\nOnly when all 5 data points have been collected:\n\n1) First suggestion (default)\n- Call the tool with {} (do not set any fields)\n\n2) Weekday questions\n(e.g. “What do you have on Tuesday?”)\n- Detect the weekday → set weekday, leave startAfter undefined\n- Example:\n → { “weekday”: 2 }\n\n3) Later / more options\n(e.g. “Do you have something later?”)\n- Remember the end of the last slot (ISO datetime)\n- → { “startAfter”: “<ISO_DATETIME>” }\n\n4) Combined\n(e.g. “Later on Friday?”)\n- Example:\n → { “weekday”: 5, “startAfter”: “<ISO_DATETIME>” }\n\n5) No slots\n- Politely inform the user\n- Then call the tool again (for example only a later startAfter or {})\n\n6) Presentation of slots\n- Only use the labels from the tool\n\n—\n\n# Booking\n\n1. Check availability (Calendar Read)\n2. If free → Calendar Create (60 min)\n3. Update Google Sheet (Appointment Date & Status=confirmed)\n4. Send confirmation mail via Gmail\n5. Reply to the user with a clear confirmation, without suggesting new slots\n\n—\n\n# Style\n\n- Answer in German\n- Use formal “Sie”\n- Be polite and precise\n- Do not show technical terms or error messages\n”
}
}
},
{
“id”: “10d53a82-ab41-4189-9551-7c46c6f3f94b”,
“name”: “Call ‘Terminfinder’”,
“type”: “@n8n/n8n-nodes-langchain.toolWorkflow”,
“typeVersion”: 2.2,
“position”: [1440, 1792],
“parameters”: {
“description”: “Call this tool to calculate free 60-minute slots based on Google Calendar data.”,
“workflowId”: {
“__rl”: true,
“value”: “OIHkToPDdqOqjJXL”,
“mode”: “list”,
“cachedResultName”: “Terminfinder”
},
“workflowInputs”: {
“mappingMode”: “defineBelow”,
“value”: {},
“matchingColumns”: [
“query”
],
“schema”: ,
“attemptToConvertTypes”: false,
“convertFieldsToString”: false
}
}
}
],
“connections”: {
“OpenAI Chat Model1”: {
“ai_languageModel”: [
[
{
“node”: “AI Agent1”,
“type”: “ai_languageModel”,
“index”: 0
}
]
]
},
“Simple Memory1”: {
“ai_memory”: [
[
{
“node”: “AI Agent1”,
“type”: “ai_memory”,
“index”: 0
}
]
]
},
“Call ‘Terminfinder’”: {
“ai_tool”: [
[
{
“node”: “AI Agent1”,
“type”: “ai_tool”,
“index”: 0
}
]
]
}
}
}

And here is my sub-workflow “Terminfinder” that is being called:

{
“nodes”: [
{
“id”: “8352e342-9483-44c3-bae4-fb06814d653e”,
“name”: “When Executed by Another Workflow”,
“type”: “n8n-nodes-base.executeWorkflowTrigger”,
“typeVersion”: 1.1,
“position”: [0, 0],
“parameters”: {
“inputSource”: “passthrough”
}
},
{
“id”: “7cc52cca-a8f8-43d0-8814-ebc7ceace406”,
“name”: “Get many events”,
“type”: “n8n-nodes-base.googleCalendar”,
“typeVersion”: 1.3,
“position”: [208, 0],
“alwaysOutputData”: true,
“parameters”: {
“operation”: “getAll”,
“calendar”: {
“__rl”: true,
“value”: “[email protected]”,
“mode”: “list”,
“cachedResultName”: “[email protected]
},
“limit”: 200,
“timeMax”: “={{ $now.plus({ days: 21 }) }}”,
“options”: {
“recurringEventHandling”: “expand”
}
}
},
{
“id”: “a5479adb-09d3-446a-b92d-d7a5d3cef42a”,
“name”: “Code in JavaScript”,
“type”: “n8n-nodes-base.code”,
“typeVersion”: 2,
“position”: [416, 0],
“parameters”: {
“mode”: “runOnceForAllItems”,
“jsCode”: “// INPUT: Events from “Get many events”\n// Optional INPUT from “When Executed by Another Workflow”:\n// - { startAfter: “…”, weekday: 3 }\n// - { query: { “weekday”: 5 } }\n// - { query: “{\“startAfter\”:\“2025-12-20T00:00:00+01:00\”,\“weekday\”:2}” }\n// - { query: “2025-12-19T00:00:00+01:00” } // interpreted as startAfter\n//\n// OUTPUT: Up to 5 free slots as items { start, end, label }\n\n// (full JS code as in my original post – logic for OFFICE_HOURS, LOOKAHEAD_DAYS, CLOSED_WORDS, parsing cfgRaw, handling startAfter and weekday,\n// building local datetimes with calendar offset, checking busy slots, collecting up to 5 free slots and returning them as [{ json: { start, end, label } }])”
}
}
],
“connections”: {
“When Executed by Another Workflow”: {
“main”: [
[
{
“node”: “Get many events”,
“type”: “main”,
“index”: 0
}
]
]
},
“Get many events”: {
“main”: [
[
{
“node”: “Code in JavaScript”,
“type”: “main”,
“index”: 0
}
]
]
}
}
}

The problem I am facing: When the user asks for specific days/times, the AI Agent should pass startAfter/weekday into the Call Terminfinder tool. I can see the input on the calling side, but inside the sub-workflow the data does not arrive in the Execute Workflow Trigger node (it looks empty), so my JS code falls back to the default behaviour and returns the first 5 free slots again.

Hi @botimy I will not be able to use the above json. If it is not in a code block this site changes the format and breaks the json so its unusable. Please share the json file on a google drive or paste bin link if it is too big

Here are the two workflows as Pastebin links:

Main workflow:

Subworkflow “Terminfinder”:

Hopefully this helps to find the issue :crossed_fingers:
Thanks again for your support!

“Hello, I’m having the same issue, so I’ll set up the tool as a code node. Thanks for sharing this; if I hadn’t seen it, I probably wouldn’t have changed my approach and would’ve kept going the wrong way.”