N8n AI Agent PostgreSQL Tool shows invalid/missing schema error (query input not working)

Problem:
I’m facing a schema-related issue in my n8n AI Agent workflow while using the PostgreSQL tool.

:gear: Setup:

  • AI Agent (LangChain)
  • PostgreSQL tool connected (Execute_a_SQL_query_in_Postgres)
  • Tool is supposed to execute SQL queries generated by the AI
  • Using input mapping: {{ $fromAI('query') }}

:red_exclamation_mark: Problem:

I’m getting errors like:

  • “invalid schema”
  • “no schema found”
  • tool is not receiving input properly

Because of this, the AI Agent is not executing the PostgreSQL tool and no database response is returned.

Instead, I only see system messages / AI reasoning output.


:magnifying_glass_tilted_left: Expected behavior:

AI should generate a SQL query and pass it to the tool in this format:


{ "query": "SELECT * FROM products;" }

:red_question_mark: What I want to know:

  • What is the correct way to define the input schema for the PostgreSQL tool in n8n AI Agent?
  • Do I need to manually define the JSON schema for the “query” parameter?
  • Why does $fromAI('query') fail when schema is not properly set?

json code :

{
“nodes”: [
{
“parameters”: {
“model”: {
“__rl”: true,
“value”: “gpt-4o”,
“mode”: “list”,
“cachedResultName”: “gpt-4o”
},
“responsesApiEnabled”: false,
“options”: {}
},
“type”: “@n8n/n8n-nodes-langchain.lmChatOpenAi”,
“typeVersion”: 1.3,
“position”: [
272,
112
],
“id”: “80240fb0-0b9f-4736-a2f9-f05874a62e88”,
“name”: “OpenAI Chat Model”,
“credentials”: {
“openAiApi”: {
“id”: “ga3qqF8DxuYDoPMz”,
“name”: “OpenAI account”
}
}
},
{
“parameters”: {
“promptType”: “define”,
“text”: “={{ $json.chatInput }}”,
“options”: {
“systemMessage”: “You are an AI Database Assistant.\n\nYou MUST use the tool “Execute_a_SQL_query_in_Postgres” to answer all queries.\n\n\nYour job:\n- Understand user question\n- Generate SQL for the “products” table only\n- Execute SQL using the provided tool\n- Return ONLY final result from the tool\n\nRules:\n- Use only table: products\n- Use only columns: id, product_name, price, tracking_id, status\n- Never invent tables or columns\n- If no data found, return “Not Found”\n\nDo NOT return SQL as text.\nYou MUST use the PostgreSQL tool for every query.”
}
},
“type”: “@n8n/n8n-nodes-langchain.agent”,
“typeVersion”: 3.1,
“position”: [
480,
-80
],
“id”: “f904ab0b-8af4-42b7-b143-35dbfd290ddb”,
“name”: “AI Agent”
},
{
“parameters”: {
“options”: {}
},
“type”: “@n8n/n8n-nodes-langchain.chatTrigger”,
“typeVersion”: 1.4,
“position”: [
144,
-80
],
“id”: “54066fdd-b86f-49f8-a126-d1df3a608f15”,
“name”: “When chat message received”,
“webhookId”: “8154f63c-2a41-43b4-b919-512dcca80946”
},
{
“parameters”: {
“descriptionType”: “manual”,
“toolDescription”: “Execute SQL queries against the PostgreSQL database.\n\nAvailable table:\n\nproducts\n- id\n- product_name\n- price\n- tracking_id\n- status\n\nUse this tool when the user asks:\n\n- product list\n- product price\n- tracking status\n- product availability\n- product information\n\nExecute PostgreSQL queries.\n\nInput:\nquery = SQL query string\n”,
“operation”: “executeQuery”,
“query”: “{{ $fromAI(‘query’) }}”,
“options”: {}
},
“type”: “n8n-nodes-base.postgresTool”,
“typeVersion”: 2.6,
“position”: [
640,
128
],
“id”: “e1958ef6-e736-4ea3-b80a-0dbe69dd9ff1”,
“name”: “Execute a SQL query in Postgres1”,
“credentials”: {
“postgres”: {
“id”: “ipP4rrIMdw1yQjM4”,
“name”: “Postgres account”
}
}
}
],
“connections”: {
“OpenAI Chat Model”: {
“ai_languageModel”: [
[
{
“node”: “AI Agent”,
“type”: “ai_languageModel”,
“index”: 0
}
]
]
},
“When chat message received”: {
“main”: [
[
{
“node”: “AI Agent”,
“type”: “main”,
“index”: 0
}
]
]
},
“Execute a SQL query in Postgres1”: {
“ai_tool”: [
[
{
“node”: “AI Agent”,
“type”: “ai_tool”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“templateCredsSetupCompleted”: true,
“instanceId”: “126c751a1f4f9bb134cc288b6b2abddd2d54dcebc1b2f7a5031e97b151f2eaef”
}
}

Hi @Hassan_Zakria

Your $fromAI() call is missing the description and type parameters.

Change your PostgreSQL tool’s query field from:

{{ $fromAI('query') }}

to:

{{ $fromAI('query', 'A valid PostgreSQL SELECT query to execute against the products table', 'string') }}

The description tells the AI Agent what format the input should be in, which is how it generates the tool’s input schema. Without it, the schema generation fails.

Let me know if it helps :crossed_fingers:

i try this bt same error occurs

Bad request - please check your parameters

Invalid schema for function ‘Execute_a_SQL_query_in_Postgres1’: schema must be a JSON Schema of ‘type: “object”’, got ‘type: “None”’.

Hi @Hassan_Zakria, houda_ben’s fix above is the right first step. If you add the description and type and it still throws “got None”, two more things: keep them as straight quotes, not curly, a curly quote in $fromAI silently breaks the parse so no parameter registers. And use type ‘string’, not ‘json’ (the json type builds a malformed schema, issue #18588).

If a correct expression still fails, it’s a known regression (#29353) where agent tools emit that exact “got None” on newer 2.x but work on ~2.15. What n8n version are you on?

version :
2.26.4 (Self Hosted)

@Hassan_Zakria that confirms it. On 2.26.4 with a correct expression still throwing “got None”, this is the open regression #29353, not your config. On these 2.x versions the Postgres tool just doesn’t emit a valid parameter schema, so no $fromAI tweak will fix it.

Two ways forward:

  1. Cleanest, no downgrade: move the SQL into a small sub-workflow (one “query” input, then your Postgres node) and attach that to the agent as a Call n8n Workflow Tool instead of the Postgres tool directly. That node lets you define the input schema explicitly, so it sends a valid object schema and sidesteps the bug.

  2. Or pin n8n to v2.15, the version the issue reporter confirmed working.

Worth subscribing to #29353 for the real fix.

ok i try sub node method


problem :

the agent write query now ,detect tool sent it but further it gerate error
may bi its integration issue between 2 nodes
execute “n8n subworkflow” node
and the “When Executed by Another Workflow”

@Hassan_Zakria you’re basically there, just one wiring fix. In the “When Executed by Another Workflow” trigger you pasted a JSON schema into “Define using JSON example”, so n8n read the fields as type/properties/required (that’s the type/properties/required = null you see feeding the Postgres node), and {{ $json.query }} resolves to nothing.

That box wants an example of the data, not a schema. Set it to:

{ "query": "SELECT * FROM products;" }

Then n8n infers a real “query” field and {{ $json.query }} in the Postgres node fills correctly. (Or switch Input data mode to “Define using fields below” and add one field, query, type string.) The schema you had belongs on the Call Workflow Tool’s input side, not the trigger.

ok i try this further

i notice when i not add properties in the json example input field
then the this invalid schema msg occurs
maybe due to i not define the type : object and required query?

yeah that screenshot clears it up, the Call Workflow Tool throws the exact same “must be type object, got None”, so swapping to it didnt actually dodge anything, my bad on that one. the bug is in how n8n builds any tool schema for the model on 2.26.x, not just the postgres tool. your subworkflow wiring itself is fine though, itll work the moment that bug is gone.

two ways out for now. the easy one is to skip the agent tool completely, let a Message a Model node write the SQL (put your table rules in the system prompt) and feed it straight into a normal Postgres node. no tool means no broken schema so it runs fine on 2.26.4, you just lose the agent loop, which for plain question-to-SQL you dont really need. otherwise downgrade to 2.15 where it still works and keep the agent + tools.