n8n-io/n8n · error · Error
Failed to convert to Langchain content block: ${JSON.stringi
Error message
Failed to convert to Langchain content block: ${JSON.stringify(block)} What it means
toLcContent() maps an n8n content block to a Langchain content block by checking block types in turn (text, reasoning, file, tool_call, invalid_tool_call, tool_result, citation, provider/non_standard). If none match, the block is of an unknown/unsupported type and cannot be represented in the Langchain content model, so it throws with the serialized block for diagnosis.
Source
Thrown at packages/@n8n/ai-utilities/src/converters/message.ts:317
}
if (isN8nCitationBlock(block)) {
return {
type: 'citation',
source: block.source,
url: block.url,
title: block.title,
startIndex: block.startIndex,
endIndex: block.endIndex,
citedText: block.text,
} as unknown as LangchainMessages.ContentBlock;
}
if (isN8nProviderBlock(block)) {
return {
type: 'non_standard',
value: block.value,
} as LangchainMessages.ContentBlock.NonStandard;
}
throw new Error(`Failed to convert to Langchain content block: ${JSON.stringify(block)}`);
}
export function toLcMessage(message: Message): LangchainMessages.BaseMessage {
const lcContent = message.content.map(toLcContent);
switch (message.role) {
case 'system':
return new LangchainMessages.SystemMessage({
content: lcContent,
id: message.id,
name: message.name,
});
case 'user':
return new LangchainMessages.HumanMessage({
content: lcContent,
id: message.id,
name: message.name,
});View on GitHub (pinned to 5ac6606e81)
Solutions
- Inspect the serialized block in the error to see its shape, then construct it using a supported type guard (text/reasoning/file/tool_*).
- If it's a genuinely new block type, add a branch + isN8nXBlock predicate to toLcContent in message.ts.
- Sanitize upstream: drop or coerce unknown blocks before conversion.
Example fix
// before
{ type: 'mystery', payload: {...} }
// after (coerce to text or drop)
{ type: 'text', text: JSON.stringify(rawBlock) } Defensive patterns
Strategy: type-guard
Validate before calling
import { isN8nTextBlock, isN8nReasoningBlock, isN8nFileBlock } from '@n8n/ai-utilities';
function isKnownBlock(b: unknown): boolean {
return isN8nTextBlock(b) || isN8nReasoningBlock(b) || isN8nFileBlock(b) /* or other supported guards */;
}
content.filter(isKnownBlock).map(toLcContent); Type guard
function isSupportedBlock(b: unknown): boolean {
return (
typeof b === 'object' && b !== null && 'type' in b &&
['text','reasoning','file','tool_call','invalid_tool_call','tool_result','citation','non_standard'].includes((b as { type: string }).type)
);
} Prevention
- Filter content through known type guards before converting.
- When adding a new n8n block type, add a branch + predicate to toLcContent the same commit.
- Log unknown block types so converter gaps surface in dev.
When it happens
Trigger: Passing a content block missing a recognized discriminator (e.g. `{ type: 'something_new' }`); a malformed block where the type guard predicates all return false; a newly added n8n block type that this converter has not been taught to handle.
Common situations: A provider returned a block shape the converter doesn't know yet (version lag); a tool/handler emitted an ad-hoc block object; schema drift between n8n message types and the converter.
Related errors
- Provided message is not a valid Langchain message: ${JSON.st
- Tool message is missing a tool-result content block
- Unable to convert tool to N8nTool: ${JSON.stringify(tool)}
- Run ${this.runId} is not suspended. Cannot resume.
- Reflector output must be valid JSON
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/86c6d236a49d4589.
Report an issue: GitHub.