{"record":{"id":"669f5bdae55fc12c","repo":"n8n-io/n8n","slug":"invalid-message-type","errorCode":null,"errorMessage":"Invalid message type","messagePattern":"Invalid message type","errorType":"exception","errorClass":"OperationalError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/promptUtils.ts","lineNumber":53,"sourceCode":"\tcontext,\n\titemIndex,\n\tmessages,\n}: {\n\tcontext: IExecuteFunctions;\n\titemIndex: number;\n\tmessages: MessageTemplate[];\n}): Promise<BaseMessagePromptTemplateLike[]> {\n\treturn await Promise.all(\n\t\tmessages.map(async (message) => {\n\t\t\t// Find the appropriate message class based on type\n\t\t\tconst messageClass = [\n\t\t\t\tSystemMessagePromptTemplate,\n\t\t\t\tAIMessagePromptTemplate,\n\t\t\t\tHumanMessagePromptTemplate,\n\t\t\t].find((m) => m.lc_name() === message.type);\n\n\t\t\tif (!messageClass) {\n\t\t\t\tthrow new OperationalError('Invalid message type', {\n\t\t\t\t\textra: { messageType: message.type },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Handle image messages specially for human messages\n\t\t\tif (messageClass === HumanMessagePromptTemplate && message.messageType !== 'text') {\n\t\t\t\treturn await createImageMessage({ context, itemIndex, message });\n\t\t\t}\n\n\t\t\t// Process text messages\n\t\t\t// Escape curly braces in the message to prevent LangChain from treating them as variables\n\t\t\treturn messageClass.fromTemplate(\n\t\t\t\t(message.message || '').replace(/[{}]/g, (match) => match + match),\n\t\t\t);\n\t\t}),\n\t);\n}\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/chains/ChainLLM/methods/promptUtils.ts#L35-L71","documentation":"Thrown by getMessagesPromptTemplates in promptUtils when a message template's 'type' does not match any of SystemMessagePromptTemplate, AIMessagePromptTemplate, or HumanMessagePromptTemplate (matched via lc_name()). The message type is unrecognized, so no LangChain prompt-template class can be selected.","triggerScenarios":"A message row in the Basic LLM Chain 'Messages' fixedCollection has a 'type' value that is not 'system', 'ai', or 'human' (e.g. a typo, a legacy value, or an injected custom value). The .find() returns undefined and OperationalError is thrown with the bad type recorded in extra.messageType.","commonSituations":"Workflow exported from an older node version with a renamed message type; user hand-edited the workflow JSON and introduced an invalid type; a template was migrated partially.","solutions":["Open the node's Messages config and set each message's type to one of: system, ai, or human.","If hand-editing workflow JSON, ensure each message.type is exactly one of the supported lc_name() values.","Delete and re-create the offending message row to clear stale fixedCollection state.","Upgrade/migrate the workflow through the supported node version path rather than editing raw JSON."],"exampleFix":"// before\nconst messageClass = [SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate]\n  .find((m) => m.lc_name() === message.type);\nif (!messageClass) {\n  throw new OperationalError('Invalid message type', { extra: { messageType: message.type } });\n}\n\n// after — enumerate accepted values in the error\nconst ACCEPTED = ['system', 'ai', 'human'];\nif (!ACCEPTED.includes(message.type)) {\n  throw new OperationalError(`Invalid message type '${message.type}'. Accepted: ${ACCEPTED.join(', ')}`, {\n    extra: { messageType: message.type },\n  });\n}","handlingStrategy":"validation","validationCode":"const VALID_TYPES = new Set(['system', 'ai', 'human']);\nfor (const m of messages) {\n  if (!VALID_TYPES.has(m.type)) {\n    throw new Error(`Invalid message type '${m.type}'. Must be system, ai, or human.`);\n  }\n}","typeGuard":"function isValidMessageType(t: unknown): t is 'system' | 'ai' | 'human' {\n  return t === 'system' || t === 'ai' || t === 'human';\n}","tryCatchPattern":null,"preventionTips":["Restrict message types to system/ai/human when authoring templates.","Recreate stale message rows through the UI rather than editing JSON.","Migrate workflows through supported version paths."],"tags":["configuration","message-template","langchain","parameter-validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}