Skip to content

Conversation

@yehorkardash
Copy link
Contributor

@yehorkardash yehorkardash commented Dec 8, 2025

Summary

This PR updates ChainLLM to support responses API and built-in OpenAI tools. Because the change can be breaking, I added a new version.

Also, fallback agent was not used when output parser was enabled. This PR enables fallback agent for all versions

2025-12-09.10-30-42.mp4

Related Linear tickets, Github issues, and Community forum posts

https://linear.app/n8n/issue/NODE-4020/community-issue-structured-output-parser-always-produces-an-error-on
closes #22182

Review / Merge checklist

  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.
  • PR Labeled with release/backport (if the PR is an urgent fix that needs to be backported)

@n8n-assistant n8n-assistant bot added the n8n team Authored by the n8n team label Dec 8, 2025
@codecov
Copy link

codecov bot commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 95.45455% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ain/nodes/chains/ChainLLM/methods/chainExecutor.ts 88.88% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@currents-bot
Copy link

currents-bot bot commented Dec 8, 2025

E2E Tests: n8n tests passed after 9m 51.3s

🟢 576 · 🔴 0 · ⚪️ 43

View Run Details

Run Details

  • Project: n8n

  • Groups: 2

  • Framework: Playwright

  • Run Status: Passed

  • Commit: 9ac009d

  • Spec files: 129

  • Overall tests: 619

  • Duration: 9m 51.3s

  • Parallelization: 9

Groups

GroupId Results Spec Files Progress
multi-main:ui 🟢 519 · 🔴 0 · ⚪️ 43 120 / 120
multi-main:ui:isolated 🟢 57 · 🔴 0 · ⚪️ 0 9 / 9


This message was posted automatically by currents.dev | Integration Settings

@yehorkardash yehorkardash marked this pull request as ready for review December 9, 2025 09:35
@blacksmith-sh

This comment has been minimized.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 5 files

Prompt for AI agents (all 3 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/chainExecutor.ts">

<violation number="1" location="packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/chainExecutor.ts:122">
P2: Rule violated: **Prefer Typeguards over Type casting**

Use a type guard instead of `as Tool[]` for type narrowing. Consider creating a type guard function like `isToolArray(value): value is Tool[]` to safely verify the type before using it.</violation>

<violation number="2" location="packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/chainExecutor.ts:153">
P2: Rule violated: **Prefer Typeguards over Type casting**

Add an explicit return type annotation to `prepareLlm` function instead of casting its return value. The function at lines 128-135 should declare its return type as `BaseChatModel | BaseLanguageModel | Runnable&lt;...&gt;`.</violation>
</file>

<file name="packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/promptUtils.ts">

<violation number="1" location="packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/promptUtils.ts:181">
P1: Rule violated: **Prefer Typeguards over Type casting**

Use a type guard instead of `as AgentFinish` for type narrowing. The file already defines `isMessage()` type guard above - create a similar `isAgentFinish()` guard:

```typescript
const isAgentFinish = (value: unknown): value is AgentFinish =&gt; {
  return typeof value === &#39;object&#39; &amp;&amp; value !== null &amp;&amp; &#39;returnValues&#39; in value;
};

Then use it: if (isAgentFinish(steps)) { ... }


</details>

<sub>Reply to cubic to teach it or ask questions. Re-run a review with `@cubic-dev-ai review this PR`</sub>

fallbackLlm,
}: ChainExecutionParams): Promise<unknown[]> {
const version = context.getNode().typeVersion;
const model = prepareLlm(llm, fallbackLlm) as BaseChatModel | BaseLanguageModel;
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Rule violated: Prefer Typeguards over Type casting

Add an explicit return type annotation to prepareLlm function instead of casting its return value. The function at lines 128-135 should declare its return type as BaseChatModel | BaseLanguageModel | Runnable<...>.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/chainExecutor.ts, line 153:

<comment>Add an explicit return type annotation to `prepareLlm` function instead of casting its return value. The function at lines 128-135 should declare its return type as `BaseChatModel | BaseLanguageModel | Runnable&lt;...&gt;`.</comment>

<file context>
@@ -134,6 +149,8 @@ export async function executeChain({
 	fallbackLlm,
 }: ChainExecutionParams): Promise&lt;unknown[]&gt; {
+	const version = context.getNode().typeVersion;
+	const model = prepareLlm(llm, fallbackLlm) as BaseChatModel | BaseLanguageModel;
 	// If no output parsers provided, use a simple chain with basic prompt template
 	if (!outputParser) {
</file context>
Fix with Cubic


// Some models nodes, like OpenAI, can define built-in tools in their metadata
function withBuiltInTools(llm: BaseChatModel | BaseLanguageModel) {
const modelTools = (llm.metadata?.tools as Tool[]) ?? [];
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Rule violated: Prefer Typeguards over Type casting

Use a type guard instead of as Tool[] for type narrowing. Consider creating a type guard function like isToolArray(value): value is Tool[] to safely verify the type before using it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/chainExecutor.ts, line 122:

<comment>Use a type guard instead of `as Tool[]` for type narrowing. Consider creating a type guard function like `isToolArray(value): value is Tool[]` to safely verify the type before using it.</comment>

<file context>
@@ -122,6 +117,26 @@ async function executeSimpleChain({
 
+// Some models nodes, like OpenAI, can define built-in tools in their metadata
+function withBuiltInTools(llm: BaseChatModel | BaseLanguageModel) {
+	const modelTools = (llm.metadata?.tools as Tool[]) ?? [];
+	if (modelTools.length &amp;&amp; isChatInstance(llm) &amp;&amp; llm.bindTools) {
+		return llm.bindTools(modelTools);
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

n8n team Authored by the n8n team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Structured Output Parser always produces an error on the latest version

2 participants