Describe the problem/error/question
Hello everyone,
I’m seeking help with a persistent issue in an AI Agent workflow where the agent fails to use a critical piece of data (conversation_id
) for a specific tool call, despite having the correct data at the start of its execution.
My Setup: I have a Telegram bot powered by an AI Agent
node (gpt-4o
model). Its purpose is to manage Google Calendar events. To allow for future updates and deletions, it saves a reference for each created event into a custom Postgres table (event_ids
). This table links the calendar’s event_id
to my Telegram conversation_id
.
The Core Problem: After a long chain of tool calls (checking for conflicts, creating the event), the AI Agent consistently fails to use the correct conversation_id
when it calls the final tool, Store_EventID
.
Key Findings & Symptoms:
- We have verified that my
Format_User_Input
node correctly prepares the data and passes the correct numeric Telegram Chat ID into theAI Agent
node at the start of every execution. - Crucially, the
Postgres Chat Memory
sub-node is working perfectly and uses the correct ID to save and retrieve conversation history. - However, when the agent later calls the
Store_EventID
tool, it uses an incorrect, “hallucinated” ID. We have seen it use random numbers (12345
), my email address, and even the literal stringuser_phone_number
. - This happens even though the system prompt contains a
CONTEXT RETENTION
core rule and explicit instructions in both the procedures and the tool definition telling it to use theconversation_id
from its initial input.
It seems the conversation_id
from the initial input is being lost or ignored from the agent’s context by the time it reaches the final tool call.
What is the error message (if any)?
There are two main behaviors:
- Most often, the workflow runs without an error message, but the data saved to the database is incorrect (as seen in the
conversation_id
column). - When switching models or making significant prompt changes, we sometimes see a
Problem in node ‘AI Agent‘: Received tool input did not match expected schema
error, which suggests the model is trying to generate parameters that don’t align with the prompt’s tool definitions.
Please share your workflow
the main flow is Telegram Trigger
→ Format_User_Input
→ AI Agent
. The AI Agent
then has many tools connected, including Find_Business_Events
, Create_Event
, and Store_EventID
)*.
Share the output returned by the last node
Store_EventID
call might be generated with a placeholder conversation_id
like “12345” instead of the real one.)*

My Request to the Community:
After extensive debugging, the issue seems to be how the AI Agent handles its context across multiple tool calls. I would be grateful for any insights:
- Has anyone successfully built a multi-step agent that needs to “remember” an ID from its initial input and use it in a final tool call after other tools have been run?
- Is there a more robust pattern for passing critical, persistent data like a
conversation_id
through an agent’s execution chain? - Why would the
Postgres Chat Memory
successfully use the correct ID, while a separate tool call (Store_EventID
) within the same agent execution fails to do so?
Thank you for your time and any help you can provide!
Information on your n8n setup
- n8n version: 1.99.1
- Database (default: SQLite): Postgres with pgadmin 4
- n8n EXECUTIONS_PROCESS setting (default: own, main): * default
- **Running n8n via : Docker, portainer nginx proxy manager ssl, n8n.
- Operating system: *Self hostes proxmox server > ubuntu VM> portainer> n8n
{
"nodes": [
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "47bc02f1-e9c2-435e-8591-49aff8d13271",
"name": "text",
"value": "={{ $json.message.text }}",
"type": "string"
},
{
"id": "e8f291f3-285e-400c-ab50-2ce032b2374f",
"name": "conversation_id",
"value": "={{ $json.message.chat.id }}",
"type": "string"
},
{
"id": "51856ce3-254a-4a86-b30a-504481c1f1b5",
"name": "firstName",
"value": "={{ $json.message.chat.first_name }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
740,
80
],
"id": "be59539a-3af2-4871-997b-4dfb1286ed1a",
"name": "Format_User_Input"
},
{
"parameters": {
"promptType": "define",
"text": "=User's Prompt: {{ $json.text }}",
"options": {
"systemMessage": "=--- CORE IDENTITY ---\nYou are a highly efficient, reliable, and helpful AI Personal Assistant for a user named {{ $json.firstName }}. You MUST respond in Telegram Markdown format.\n\n--- CORE RULES ---\n1. You must always use a tool to fulfill a user's request. Do not answer from your general knowledge.\n2. When calling a tool, respond with ONLY the raw JSON object for the tool call.\n3. Infer all required parameters from the user's message and context. If a parameter is missing, ask the user.\n4. **CONTEXT RETENTION:** The user's numeric Telegram Chat ID is provided as `conversation_id` in the initial input. This ID is essential for all database operations. You MUST retain this ID in your working memory throughout the entire task, even across multiple tool calls. When a tool requires `conversation_id`, you must recall and use this original value.\n\n--- CONTEXT ---\n- The current date and time is: {{ $now.toISO() }}\n- The user's current location is: Maroubra, New South Wales, Australia.\n\n--- PROCEDURES & WORKFLOWS ---\n\n**1. For Schedule Requests (e.g., \"what's on for tomorrow?\"):**\n A. First, call `get_current_datetime()` to get the current date as a reference.\n B. From the user's request, determine the target date (e.g., \"today\", \"tomorrow\").\n C. Calculate the exact start-of-day and end-of-day ISO-8601 timestamps for that target date.\n D. Call both `Find_Business_Events` and `Find_Family_Events` using the calculated timestamps for `start_time` and `end_time`.\n E. Format the results into a single chronological list.\n\n**2. For Creating Events (e.g., \"book a meeting\"):**\n A. Extract the event details (`summary`, `start_time`, `end_time`) from the user's request.\n B. Check for conflicts by calling `Find_Business_Events` and `Find_Family_Events`. You MUST use the exact start and end times for the `start_time` and `end_time` parameters. An event that ends exactly when the new event begins is NOT a conflict.\n C. If the check returns ZERO events, you MUST ask for confirmation using this exact script: \"The slot from [start time] to [end time] is available. Shall I book '[summary]' for you?\". If it returns an event, inform the user of the specific conflict and stop.\n D. On user confirmation, call the `Create_Event` tool.\n E. After successful creation, call `Store_EventID`. For the `conversation_id` parameter, you MUST use the numeric Telegram Chat ID provided at the start of the workflow.\n\n**3. For Updating or Deleting Events (e.g., \"change my meeting\"):**\n A. First, call `get_event_details_from_db` to get the event's unique ID.\n B. Use the returned `event_id` to call `Update_Event` or `Delete_Event`.\n C. If the event was updated, call `Update_EventID` to sync the changes.\n\n--- AVAILABLE TOOLS ---\n\n- get_current_datetime\n // Description: Returns the current date and time as an ISO-8601 string.\n Parameters: {}\n\n- Find_Contact\n // Description: Finds contact information for a person.\n Parameters: {\n \"name\": \"<string>\" // The name of the person to find.\n }\n\n- Find_Business_Events\n // Description: Finds events on the business calendar within a given time range.\n Parameters: {\n \"start_time\": \"<ISO-8601 timestamp>\", // The start of the time range to search.\n \"end_time\": \"<ISO-8601 timestamp>\" // The end of the time range to search.\n }\n\n- Find_Family_Events\n // Description: Finds events on the family calendar within a given time range.\n Parameters: {\n \"start_time\": \"<ISO-8601 timestamp>\", // The start of the time range to search.\n \"end_time\": \"<ISO-8601 timestamp>\" // The end of the time range to search.\n }\n\n- Create_Event\n // Description: Creates a new event on the calendar.\n Parameters: {\n \"summary\": \"<string>\", // The title or summary of the event.\n \"start_time\": \"<ISO-8601 timestamp>\", // The exact start time of the event.\n \"end_time\": \"<ISO-8601 timestamp>\" // The exact end time of the event.\n }\n\n- Update_Event\n // Description: Updates an existing event on the calendar.\n Parameters: {\n \"event_id\": \"<string>\", // CRITICAL: This MUST be the ID returned from `get_event_details_from_db`.\n \"start_time\": \"<ISO-8601 timestamp>\", // Optional: The new start time.\n \"end_time\": \"<ISO-8601 timestamp>\", // Optional: The new end time.\n \"summary\": \"<string>\" // Optional: The new summary.\n }\n\n- Delete_Event\n // Description: Deletes an event from the calendar.\n Parameters: {\n \"event_id\": \"<string>\" // CRITICAL: This MUST be the ID returned from `get_event_details_from_db`.\n }\n\n- Store_EventID\n // Description: Saves a new event's details to the database.\n Parameters: {\n \"conversation_id\": \"<string>\", // CRITICAL: This MUST be the numeric Telegram Chat ID from the start of the workflow. DO NOT use any other ID, email, name, or placeholder.\n \"event_id\": \"<string>\",\n \"event_summary\": \"<string>\",\n \"event_start_time\": \"<ISO-8601 timestamp>\"\n }\n\n- Update_EventID\n // Description: Updates an existing event's details in the database after a change.\n Parameters: {\n \"conversation_id\": \"<string>\", // CRITICAL: This MUST be the numeric Telegram Chat ID from the start of the workflow.\n \"event_id\": \"<string>\",\n \"event_summary\": \"<string>\",\n \"event_start_time\": \"<ISO-8601 timestamp>\"\n }\n\n- get_event_details_from_db\n // Description: Finds the last event a user created to get its unique ID for updates or deletions.\n Parameters: {\n \"conversation_id\": \"<string>\" // CRITICAL: This MUST be the numeric Telegram Chat ID from the start of the workflow.\n }\n\n- Send_Email\n // Description: Sends an email.\n Parameters: {\n \"recipient\": \"<string>\", // The email address of the recipient.\n \"subject\": \"<string>\",\n \"body\": \"<string>\"\n }\n\n- Find emails\n // Description: Searches for emails matching a query.\n Parameters: {\n \"query\": \"<string>\" // The search query (e.g., from:, subject:, has:attachment).\n }\n\n- Draft email\n // Description: Creates a draft email in Gmail.\n Parameters: {\n \"subject\": \"<string>\",\n \"body\": \"<string>\"\n }"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2,
"position": [
1060,
80
],
"id": "9ae5f4c7-f572-40d4-8a4a-b08a18e9b936",
"name": "AI Agent"
}
],
"connections": {
"Format_User_Input": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[]
]
}
},
"pinData": {},
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "e4f3c192e5a1f58262e7d68f44201b5d1ed30ae590faa32b0c5de0d15c0dc146"
}
}
{
"nodes": [
{
"parameters": {
"schema": {
"__rl": true,
"mode": "list",
"value": "public"
},
"table": {
"__rl": true,
"value": "event_ids",
"mode": "list",
"cachedResultName": "event_ids"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"conversation_id": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('conversation_id', ``, 'string') }}",
"event_id": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('event_id', ``, 'string') }}",
"event_summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('event_summary', ``, 'string') }}",
"event_start_time": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('event_start_time', ``, 'string') }}"
},
"matchingColumns": [
"id"
],
"schema": [
{
"id": "id",
"displayName": "id",
"required": false,
"defaultMatch": true,
"display": true,
"type": "number",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "conversation_id",
"displayName": "conversation_id",
"required": true,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "event_id",
"displayName": "event_id",
"required": true,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "created_at",
"displayName": "created_at",
"required": false,
"defaultMatch": false,
"display": true,
"type": "dateTime",
"canBeUsedToMatch": true,
"removed": true
},
{
"id": "event_summary",
"displayName": "event_summary",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "event_start_time",
"displayName": "event_start_time",
"required": false,
"defaultMatch": false,
"display": true,
"type": "dateTime",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.postgresTool",
"typeVersion": 2.6,
"position": [
800,
680
],
"id": "0fa93d30-ce4e-43a3-ad9b-bca47c0a0add",
"name": "Store_EventID",
"credentials": {
"postgres": {
"id": "SnMZoH0YXsa9Jdek",
"name": "Postgres account"
}
}
}
],
"connections": {
"Store_EventID": {
"ai_tool": [
[]
]
}
},
"pinData": {},
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "e4f3c192e5a1f58262e7d68f44201b5d1ed30ae590faa32b0c5de0d15c0dc146"
}
}