{"record":{"id":"6cd2a4d8a00ae62d","repo":"n8n-io/n8n","slug":"the-file-content-is-not-in-jsonl-format-6cd2a4","errorCode":null,"errorMessage":"The file content is not in JSONL format","messagePattern":"The file content is not in JSONL format","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/v2/actions/file/upload.operation.ts","lineNumber":101,"sourceCode":"\n\ttry {\n\t\tconst response = await apiRequest.call(this, 'POST', '/files', {\n\t\t\toption: { formData },\n\t\t\theaders: formData.getHeaders(),\n\t\t});\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tjson: response,\n\t\t\t\tpairedItem: { item: i },\n\t\t\t},\n\t\t];\n\t} catch (error) {\n\t\tif (\n\t\t\terror.message.includes('Bad request') &&\n\t\t\terror.description?.includes('Expected file to have JSONL format')\n\t\t) {\n\t\t\tthrow new NodeOperationError(this.getNode(), 'The file content is not in JSONL format', {\n\t\t\t\tdescription:\n\t\t\t\t\t'Fine-tuning accepts only files in JSONL format, where every line is a valid JSON dictionary',\n\t\t\t});\n\t\t}\n\t\tthrow error;\n\t}\n}\n","sourceCodeStart":83,"sourceCodeEnd":109,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/v2/actions/file/upload.operation.ts#L83-L109","documentation":"When uploading a fine-tuning file via the v2 OpenAI node, the API returns a 'Bad request' error with description 'Expected file to have JSONL format' if the file is not valid JSONL. The catch block detects this pattern and rethrows as a NodeOperationError with a user-friendly description. This is identical logic to the v1 file upload (error 890), duplicated across node versions.","triggerScenarios":"A file uploaded with purpose 'fine-tune' is not in JSONL format. The OpenAI API validates server-side and returns a 400. The catch block pattern-matches on error.message containing 'Bad request' and error.description containing 'Expected file to have JSONL format'.","commonSituations":"Uploading a .json array file instead of .jsonl; uploading CSV or plain text for fine-tuning; malformed JSONL with invalid JSON lines; wrong file selected via binary input.","solutions":["Convert the file to JSONL format — one JSON object per line, no array wrapper","Validate each line is valid JSON: run cat file.jsonl | python -m json.tool --json-lines to check","Ensure correct binary property name is selected in the node","If building the file programmatically, use JSON.stringify per line followed by newline"],"exampleFix":"// before — [{\"prompt\": \"...\", \"completion\": \"...\"}]\\n (JSON array)\n// after  — {\"prompt\": \"...\", \"completion\": \"...\"}\\n{\"prompt\": \"...\", \"completion\": \"...\"}\\n (JSONL)","handlingStrategy":"validation","validationCode":"// Validate JSONL format before uploading\nfunction validateJsonl(content: string): boolean {\n  const lines = content.trim().split('\\n').filter(l => l.trim());\n  return lines.length > 0 && lines.every(line => {\n    try { JSON.parse(line); return true; } catch { return false; }\n  });\n}\nif (!validateJsonl(fileContent)) {\n  throw new UserError('File is not valid JSONL. Each line must be a valid JSON object.');\n}","typeGuard":"function isJsonlContent(content: string): boolean {\n  if (!content.includes('\\n')) return false;\n  return content.trim().split('\\n').every(line => {\n    try { JSON.parse(line); return true; } catch { return false; }\n  });\n}","tryCatchPattern":"try {\n  await uploadFile(this, i);\n} catch (error) {\n  if (error instanceof NodeOperationError && error.message.includes('JSONL')) {\n    const converted = convertToJsonl(fileContent);\n    await uploadJsonlString(this, i, converted);\n  }\n  throw error;\n}","preventionTips":["Validate JSONL format before uploading — one JSON object per line","Never use a JSON array wrapper; each line is independent","Convert with: cat data.json | jq -c '.[]' > data.jsonl","Verify the correct binary property name is selected in the node"],"tags":["openai","file-upload","jsonl","fine-tuning","format-validation","v2"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}