recent
🔥 𝐇𝐨𝐭

n8n AI Agent Not Calling Tools? Diagnose and Fix the Cause

Home
n8n AI Agent not calling tools, illustrated with a broken connection and a magnifying glass highlighting the issue.

If your n8n AI Agent is not calling tools, identify where the request stopped. The model may have skipped the tool, its definition or arguments may have been rejected, or the tool may have run and failed. A successful tool result can also be ignored in the answer. This guide covers the AI Agent node inside workflows and gives you a small test to separate those outcomes.

Quick answer: Open one failing execution. Decide whether a call was requested, whether the tool body actually ran, and whether its result reached the final answer. Change one variable, rerun, and keep both executions.

Documentation and published reports reviewed October 8, 2026. The fixture JavaScript was checked locally; the workflow and model behavior were not tested end-to-end in n8n. The test table later in this article gives expected observations, not observed model results.

Check what "not calling tools" means in your execution

The Tools Agent uses a structured tool-calling interface built on tool schemas. So text that looks like a call is only text until the trace shows a real invocation. Work through the run in this order before changing anything:

  1. Pick the exact run. Record its execution ID, timestamp, input, and n8n release. Record each AI node's version too; workflow exports identify it as typeVersion.
  2. Confirm the intended branch ran and that the input is not pinned or stale.
  3. Inspect the AI Agent output and, if you enabled Return Intermediate Steps, the intermediate steps. Trace fields can differ between releases, so don't expect an identical layout.
  4. Inspect the tool node and any linked child execution. Keep four things apart: the request, the attempted start, the completed execution, and the returned result.
  5. Compare the returned fields with the final answer. A tool can succeed and the answer can still be wrong.
  6. Change one variable and rerun, keeping the before and after executions.

A tool name in exported configuration proves only that it was configured. Likewise, a new sheet row could come from another branch. Use runtime records tied to this execution; if the relevant data is unavailable, capture a fresh run before classifying it.

Match the symptom to the right correction

Start here if you already have a failing workflow. This table is a diagnostic synthesis, not a list of proven causes for every installation.

Observation Inspect first Targeted action Verification
Agent never reached a model decision Prompt value, Chat Model connection, upstream branch and errors Connect a Chat Model. Check the resolved prompt; automatic input expects chatInput, while a custom field needs Define below. The agent receives the intended nonempty question and runs.
Agent answers without an expected call Complete execution, tool connection, task wording, tool description, actual model integration Make the tool's purpose and trigger precise. Isolate one read-only tool. Check model compatibility. A genuine invocation with matching arguments and returned data.
Final text contains functionCall, a tool name, or call-like JSON The tool and agent trace, not the wording Confirm whether the provider or integration returned a structured call. Simplify the configuration. The tool path demonstrably executed. JSON-looking text is not enough.
Provider rejects a tool definition The error stage and, if available, the serialized schema Check declared input names and types, then refresh the tool inputs. A malformed schema needs a configuration or integration fix. The definition is accepted. Then check selection and execution separately.
Selected call has invalid arguments Requested argument names and types, required values, the receiving node's error Align field names and types. Refresh Workflow Inputs and inspect the expressions. The receiving workflow gets the intended product_id and the lookup body runs.
Call is selected but waits or is canceled Any human-review step and its state Inspect approval, denial, or pending status. A permitted action runs only after approval. Waiting is not a skipped decision.
Call requested; child workflow does not start Returned launch error, selected workflow, calling permissions and publication Correct the launch error. Database-selected sub-workflows must be published for production agent calls. A matching child execution starts with the intended input.
Tool body starts and fails Execution of the failing node, API or credential error, exception Fix the error at that node, then rerun the same request. The tool completes and its result reaches the agent.
Tool returns not_found or an empty result Query arguments and raw output Handle absent data explicitly. The answer honestly reports no result instead of inventing data. This is not automatically a runtime failure.
Successful data is ignored or contradicted Returned values versus the final answer, result size and shape, session context Return concise, labeled data and state how to treat it. Isolate context effects. Material facts in the final answer agree with the result in that run.
Trace is missing or incomplete Execution identity, filters, saved-data settings, pinning, tool and child records Capture a fresh, complete run. Classify only once the evidence separates the paths.

Corrections that match the diagnosis

  • Tool purpose. "Get product details" is vague. Name the operation, the required identifier, and the possible outcomes, as the example below does.
  • Prompt. "Use tools when needed" leaves the decision open. Say when a fresh lookup is required and how to report failure or absent data. Instructions can't repair an invalid schema or an incompatible integration.
  • Input contract. If the receiving field is product_id, sku won't map itself, and a product name doesn't meet an ID-only contract. Ask for the ID or build a deliberate name-to-ID lookup.
  • Required output parser. A parser governs the final answer's shape, not whether your tool ran. For output-format failures, see how to fix n8n's model output format error.

For a model comparison, keep other settings fixed and record the provider, exact model ID, node, endpoint, and versions. A successful swap narrows the investigation; it does not identify the cause.

Build a small read-only tool-calling test

Use two disposable workflows, a chat-model credential with tool-calling support, and the fictional lookup below. No external product database is needed. Enable saving manual and successful/failed execution data for the test where available. Send one input item per run: workflow-tool sub-node expressions use the first item.

Design of the tool-calling diagnostic Workflow A runs Manual Trigger, Edit Fields, then AI Agent on its main path. A chat model and a Call n8n Workflow Tool attach to the agent as sub-nodes. The tool starts workflow B, where an Execute Sub-workflow Trigger feeds a regular Code node. Workflow A: caller Workflow B: fixture Manual Trigger Edit Fields "Test Input" AI Agent Chat Model Call n8n Workflow Tool lookup_product_reference Attach the model and tool to the agent's dedicated connectors. They are separate from the solid main execution path. A selected tool call starts workflow B. Execute Sub-workflow Trigger (product_id) Code (regular node) returns one item Main execution path Sub-node connection or tool call
Conceptual design, not an n8n screenshot. The tool is attached to the agent's Tools connector; it does not run automatically after the agent on the main path.

Build workflow B first

  1. Create B with an Execute Sub-workflow Trigger (also listed as When Executed by Another Workflow). Choose Define using fields below; add a String field named product_id.
  2. Connect a regular Code node set to JavaScript and Run Once for All Items. Paste the code below. Leave On Error set to Stop Workflow and Retry On Fail off so T4 exposes the exception.
  3. Save B. For Database source in production, publish B; n8n documents manual/chat tests separately. Check the executed revision after later edits.
// Tester controls these constants; the model cannot choose them.
const TEST_MODE = 'normal'; // 'normal' or 'tool_failure'
const FIXTURE_REVISION = 'A'; // 'A' or 'B'

if (!['normal', 'tool_failure'].includes(TEST_MODE)) {
  throw new Error('AIP_INVALID_TEST_MODE');
}
if (!['A', 'B'].includes(FIXTURE_REVISION)) {
  throw new Error('AIP_INVALID_FIXTURE_REVISION');
}

const items = $input.all();
if (items.length !== 1) {
  throw new Error('AIP_EXPECTED_ONE_INPUT_ITEM');
}
const productId = items[0].json?.product_id;
if (typeof productId !== 'string' || productId.length !== 9 ||
    !/^PROD-\d{4}$/.test(productId)) {
  throw new Error('AIP_INVALID_PRODUCT_ID');
}

if (TEST_MODE === 'tool_failure') {
  throw new Error('AIP_CONTROLLED_TOOL_FAILURE');
}

const records = {
  'PROD-4821': {
    product: 'Aurora Desk Lamp',
    reference_code: FIXTURE_REVISION === 'A'
      ? 'REF-AUR-4821-QX' : 'REF-AUR-4821-ZR',
  },
  'PROD-7394': {
    product: 'Nimbus Air Purifier',
    reference_code: FIXTURE_REVISION === 'A'
      ? 'REF-NIM-7394-KL' : 'REF-NIM-7394-M2',
  },
};
const found = Object.prototype.hasOwnProperty.call(records, productId);
const record = found ? records[productId] : null;

return [{
  json: {
    product_id: productId,
    status: found ? 'found' : 'not_found',
    product: record ? record.product : null,
    reference_code: record ? record.reference_code : null,
    fixture_revision: FIXTURE_REVISION,
  },
}];

The accepted format is PROD- followed by four digits. It is deliberately not a list of existing products: a well-formed unknown ID has to reach the lookup so it can return not_found. Missing or malformed input raises a separate validation exception.

Configure workflow A

Create A with Manual Trigger → Edit Fields → AI Agent on the main path. Rename Edit Fields to Test Input exactly; the optional memory expression uses that name.

  1. In Test Input, add String fields question and session_key. Set question to What is the reference code for PROD-4821? and session_key to aip-T1-01.
  2. In the AI Agent, choose Define below and set the user message to {{ $json.question }}. Under Options, add the instructions below as the System Message and enable Return Intermediate Steps.
  3. Use the agent's Chat Model connector to add your provider's model node. Select its credential and a model that supports tool calling; record the exact model ID.
  4. Attach a Call n8n Workflow Tool through the agent's Tools connector, name it lookup_product_reference, choose B with source Database, and refresh its inputs. If B restricts callers, allow A in B's This workflow can be called by setting. Fill product_id with the model-defined parameter control, or with this expression in expression mode:
{{ $fromAI('product_id', 'The exact PROD- followed by four digits supplied by the user', 'string') }}

The first argument of $fromAI() is a name the model sees, not a reference to an existing JSON property. String is the documented default; naming it keeps the example clear. The function isn't supported inside the Code Tool, so this example uses a workflow tool.

  1. Add the tool description below. Leave Require Specific Output Format off, and disconnect memory, extra tools, and nested agents. Record the iteration setting.
  2. Save A, execute the whole workflow, and inspect the agent and child execution. B's last node supplies its result; no response node is needed. session_key only matters when memory is connected in T3.

Tool description

Look up the current reference code for one product ID in the product
fixture. Input: product_id, a string in the form PROD- followed by four
digits. Use this tool when the user requests a reference code and supplies
a product ID. A successful lookup returns status "found", reference_code,
and fixture_revision. An unknown ID returns status "not_found". A tool
error is a failed lookup, not evidence that the product does not exist.

System instructions

You are a read-only product-reference assistant.

When the user requests a reference code and provides a product ID in the
form PROD- followed by four digits, call lookup_product_reference with
that exact ID. Perform a fresh lookup for each such request, even if an
earlier message discussed the same product.

Answer using the reference_code returned by the current successful call.
Do not substitute a code from conversation history or invent one.
If status is "not_found", say that the fixture contains no reference code
for that ID. If the tool fails, report that the lookup failed; do not turn
an error into "not found" or a successful product answer.

If a reference-code request has no valid product ID, ask for it.
For general explanations that do not request a product lookup, answer
without calling the tool. Do not claim that a lookup succeeded without a
successful tool result. Do not retry a failed lookup in this diagnostic.

Keep reference codes out of the question, system prompt, seeded history, and tool description. Instructions request behavior; verify the actual call and returned data.

Verify normal calls, repeated requests, and failures

Keep both execution IDs, requested arguments, tool output/error, final answer, versions, session setup, and fixture revision. Use the recording header below; mark unavailable evidence as such.

Case Setup and question Expected evidence Interpretation
T1: tool required Normal mode, revision A, no memory. "What is the reference code for PROD-4821?" A real invocation with product_id equal to PROD-4821. B returns REF-AUR-4821-QX. The final answer matches. Confirms this route. A matching answer without execution evidence is inconclusive.
T2: no tool required Normal mode, fresh independent run. "Explain what a product reference code is." A general explanation and no fixture call in a complete trace. Negative control for unnecessary calls. It says nothing about lookup reliability.
T3: repeated request with memory The sequence below, in a suitable test environment. Compare actual calls and the revision B results in the reused and fresh sessions. Tests freshness under changed context. A difference alone doesn't establish a memory bug.
T4: actual tool failure Optional memory disconnected. Set TEST_MODE = 'tool_failure'. Ask the T1 question. B reaches the Code node and throws AIP_CONTROLLED_TOOL_FAILURE. Capture what reaches A and whether A reports a failure or the workflow stops. No invented code. Separates a requested call, a failed tool body, and graceful reporting. If nothing reaches B, failure handling hasn't been tested.
T5: no result (optional) Restore normal mode. Ask for PROD-0000. B completes with not_found and a null reference code. The answer reports absent fixture data. A normal negative lookup, distinct from the exception in T4.

After T4, restore TEST_MODE = 'normal'. A reported tool error does not necessarily fail A, and these manual runs do not test Error Workflow routing even if A fails. For automatic-run alerts, see how to troubleshoot an n8n Error Trigger that is not running.

Optional: the T3 memory experiment, step by step

Attach Simple Memory to A's memory connector. Choose an explicit Session Key, map {{ $('Test Input').first().json.session_key }}, and pick a context window that covers the previous exchange. Simple Memory is documented as unsuitable for active production workflows in queue mode; use another backend if that's your deployment.

  1. Normal mode, revision A, new key aip-T3-shared-01. Ask: "What is the reference code for PROD-7394?" First verify a genuine call returns REF-NIM-7394-KL; keep its trace.
  2. Set the fixture to revision B and save/publish as appropriate. Keep the session key and ask: "Look up the current reference code for PROD-7394 again." Inspect whether a new call occurs; its output should report B and REF-NIM-7394-M2.
  3. Keep revision B and every model and tool setting unchanged. Repeat the second question with a fresh key such as aip-T3-fresh-01.
  4. Compare the two revision B runs. If one returns revision A, check publication, the selected workflow, pinning, and whether a new call was made at all. Without a complete trace, record the result as inconclusive.

An explicit ID avoids testing pronoun resolution at the same time. Repeat an apparent difference before attributing it to memory. Restore normal mode and revision A afterward.

Optional: a blank CSV header for recording runs

This is a recording aid, not a results table.

case_id,execution_id,child_execution_id,n8n_version,agent_node_version,model_node_version,tool_node_version,provider,model_id,session_key,fixture_revision,test_mode,call_requested,tool_body_ran,arguments_valid,tool_result_or_error,final_answer,answer_matches_result,notes

What published cases can, and cannot, tell you

These are published user reports, not AI Promix reproductions, and a reporter's explanation of their own cause is not a confirmed diagnosis.

Case A: prompt size and tool descriptions

In issue #37840, opened September 4, 2026, the reporter used n8n 2.31.0 in Docker, an AI Agent node at typeVersion 1.7, and an Anthropic model. Tools were called with a short system message and skipped with one of roughly 50 KB. The updated description separates a missing-description combination from a large-prompt case where the description was already present. The issue was still open when reviewed.

Takeaway: test prompt length and tool description as two separate variables. The 50 KB figure is one reporter's observation, not a product limit, and trimming a prompt is not a guaranteed fix.

Case B: a schema error mistaken for tool avoidance

A community thread from May and June 2026 involves a SQL tool on n8n 2.20.6, self-hosted via npm on Windows Server, with Azure OpenAI. The error is about an invalid root schema type. A June 5 follow-up reports a field-configuration workaround, and replies conflict on cause and version advice.

Takeaway: a rejected schema is not an agent choosing not to act, and it doesn't show the tool body ran. Treat the workaround as that reporter's fix, not a rule to drop the braces around $fromAI(); the documentation shows the braced form.

Case C: a nested-agent failure with a documented fix

A September 2026 report describes n8n 2.38.6 and an engine-request error when an agent uses another agent with its own tools. The reporter says the same HTTP tool works when attached directly to the main agent.

A later fix makes the version combination important. PR #39160, merged September 22, addresses an AI Agent Tool v3 calling its own tools under a parent AI Agent older than v3. The n8n 2.42.0 release entry, dated September 29, lists this fix. These node versions are distinct from the n8n application release.

Takeaway: check both node versions. If your configuration matches, test a release containing this fix on a workflow copy and verify the sub-agent's actual tool execution. For other nested failures, compare direct attachment with nesting; this fix does not establish a solution for every combination.

When the lookup should be a normal workflow step

A prompt states what you want; it can't guarantee it. If a lookup must happen on every qualifying request, put it in ordinary workflow logic with explicit validation and branching, then let the model interpret the result afterward.

Use an agent when selecting an action is part of the task. For this example, an ID-based lookup required every time can be validated and executed before the model writes its answer.

Don't assume every n8n model node exposes a provider-specific way to require a tool call; check the particular node before building around one.

Frequently asked questions

Why does my agent answer without using the tool?

The model may have judged it could answer directly, or the tool may never have been a usable option. Check the tool connection, the description, and whether the integration supports tool calling, then classify the run with the table above.

Does functionCall text in the answer mean a tool ran?

No. Call-shaped text alone proves nothing. A recorded call request shows selection; execution of the tool body shows it started. The body can then return data or throw an exception. Inspect those stages separately.

Can a prompt force the agent to call a tool every time?

Not reliably. Wording can raise the odds but doesn't enforce anything. A step that must always run belongs in workflow logic.

Why does a fresh session behave differently from a reused one?

Session memory changes the context the model sees, which can change whether it repeats a lookup. A difference alone isn't proof of a memory defect. Rule out publication state, pinned data, and whether a new call was made, then use the T3 experiment.

Why does the tool work on its own but fail through the agent?

An isolated run confirms the tool path only. Through the agent, the model must also choose the tool and produce valid arguments, and each extra component adds another place to look. Add components back one at a time.

Your next step

Open one failing execution. Classify it using the table, change one variable, and keep the next run's execution ID alongside the first. That pair of records is what tells you whether the fix worked.

X