Help Needed: AI Agent Loses conversation_id Context on Final Tool Call

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 the AI 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 string user_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 the conversation_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:

  1. 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).
  2. 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 TriggerFormat_User_InputAI 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.)*


unnamed (1)

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:

  1. 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?
  2. Is there a more robust pattern for passing critical, persistent data like a conversation_id through an agent’s execution chain?
  3. 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"
  }
}