n8n-io/n8n · error · NodeOperationError
The file content is not in JSONL format
Error message
The file content is not in JSONL format
What it means
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.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/v2/actions/file/upload.operation.ts:101
try {
const response = await apiRequest.call(this, 'POST', '/files', {
option: { formData },
headers: formData.getHeaders(),
});
return [
{
json: response,
pairedItem: { item: i },
},
];
} catch (error) {
if (
error.message.includes('Bad request') &&
error.description?.includes('Expected file to have JSONL format')
) {
throw new NodeOperationError(this.getNode(), 'The file content is not in JSONL format', {
description:
'Fine-tuning accepts only files in JSONL format, where every line is a valid JSON dictionary',
});
}
throw error;
}
}
View on GitHub (pinned to 5ac6606e81)
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
Example fix
// before — [{"prompt": "...", "completion": "..."}]\n (JSON array)
// after — {"prompt": "...", "completion": "..."}\n{"prompt": "...", "completion": "..."}\n (JSONL) Defensive patterns
Strategy: validation
Validate before calling
// Validate JSONL format before uploading
function validateJsonl(content: string): boolean {
const lines = content.trim().split('\n').filter(l => l.trim());
return lines.length > 0 && lines.every(line => {
try { JSON.parse(line); return true; } catch { return false; }
});
}
if (!validateJsonl(fileContent)) {
throw new UserError('File is not valid JSONL. Each line must be a valid JSON object.');
} Type guard
function isJsonlContent(content: string): boolean {
if (!content.includes('\n')) return false;
return content.trim().split('\n').every(line => {
try { JSON.parse(line); return true; } catch { return false; }
});
} Try / catch
try {
await uploadFile(this, i);
} catch (error) {
if (error instanceof NodeOperationError && error.message.includes('JSONL')) {
const converted = convertToJsonl(fileContent);
await uploadJsonlString(this, i, converted);
}
throw error;
} Prevention
- 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
When it happens
Trigger: 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'.
Common situations: 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.
Related errors
- The file content is not in JSONL format
- This model is not supported in ${version} version of the Age
- This fallback model is not supported in ${version} version o
- Conversation ID is required
- Metadata is required
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/6cd2a4d8a00ae62d.
Report an issue: GitHub.