{"record":{"id":"67687a36fd8c61de","repo":"n8n-io/n8n","slug":"model-output-doesn-t-fit-required-format-67687a","errorCode":null,"errorMessage":"Model output doesn't fit required format","messagePattern":"Model output doesn't fit required format","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/chains/TextClassifier/TextClassifier.node.ts","lineNumber":279,"sourceCode":"\t\t\t\t\t\tmultiClassPrompt,\n\t\t\t\t\t\tfallbackPrompt,\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((response, batchItemIndex) => {\n\t\t\t\t\tconst index = i + batchItemIndex;\n\t\t\t\t\tif (response.status === 'rejected') {\n\t\t\t\t\t\tconst error = wrapLangChainParserError(response.reason, this.getNode(), index);\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\treturnData[0].push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: index },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst output = response.value;\n\t\t\t\t\t\tconst item = items[index];\n\n\t\t\t\t\t\tcategories.forEach((cat, idx) => {\n\t\t\t\t\t\t\tif (output[cat.category]) returnData[idx].push(item);\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (fallback === 'other' && output.fallback)\n\t\t\t\t\t\t\treturnData[returnData.length - 1].push(item);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Add delay between batches if not the last batch\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/chains/TextClassifier/TextClassifier.node.ts#L261-L297","documentation":"Thrown by the Text Classifier when a Promise.allSettled batch promise rejected, continueOnFail is false, and the rejection could not be re-interpreted by wrapLangChainParserError into a softer form. The LLM output did not match the StructuredOutputParser schema (the boolean flags per category), so the parser rejected it.","triggerScenarios":"For an item in the batch, the LLM returned text that could not be parsed into the expected {category: boolean} structure. allSettled marks it rejected; with continueOnFail off, the wrapped error becomes a NodeOperationError.","commonSituations":"LLM returns free text or hallucinated category names; schema is ambiguous; weak model; high temperature; too many categories confusing the model; customized system prompt template broke the format.","solutions":["Enable Continue On Fail so failing items return an error JSON rather than aborting the batch.","Reduce the number of categories or make their descriptions clearer and mutually exclusive.","Use a stronger instruction-tuned model and lower the temperature.","Restore the default system prompt template if it was customized."],"exampleFix":"// before — aborts whole run on first rejection\nif (response.status === 'rejected') {\n  const error = wrapLangChainParserError(response.reason, this.getNode(), index);\n  if (this.continueOnFail()) {\n    returnData[0].push({ json: { error: error.message }, pairedItem: { item: index } });\n    return;\n  } else {\n    throw new NodeOperationError(this.getNode(), error);\n  }\n}\n\n// after — keep raw reason for debugging\nif (response.status === 'rejected') {\n  const error = wrapLangChainParserError(response.reason, this.getNode(), index);\n  returnData[0].push({ json: { error: error.message, raw: String(response.reason) }, pairedItem: { item: index } });\n  if (!this.continueOnFail()) {\n    throw new NodeOperationError(this.getNode(), error);\n  }\n  return;\n}","handlingStrategy":"fallback","validationCode":"// Pre-flight: confirm model and categories are sound\nif (!llm) throw new Error('Connect a chat model');\nif (categories.length === 0) throw new Error('Add categories first');","typeGuard":null,"tryCatchPattern":"try {\n  const out = await parser.parse(llmOutput);\n} catch (e) {\n  // Continue per-item with an error JSON so the batch survives\n  returnData[0].push({ json: { error: (e as Error).message }, pairedItem: { item: index } });\n}","preventionTips":["Enable Continue On Fail to isolate failing items.","Keep categories few and clearly distinct.","Use a strong instruction-tuned model and lower temperature.","Restore the default system prompt template if customized."],"tags":["llm-output","parsing","schema","text-classifier","batch"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}