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, the OpenAI 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 specific error pattern and rethrows as a NodeOperationError with a user-friendly description explaining that fine-tuning requires JSONL format where every line is a valid JSON dictionary. Other errors are rethrown unchanged.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/vendors/OpenAi/v1/actions/file/upload.operation.ts:92
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, no trailing commas
- Validate each line parses as JSON before uploading (e.g. cat file.jsonl | jq -c . > /dev/null)
- Ensure the file extension and content type match — use .jsonl with application/jsonl or text/plain
- If using a binary file input, confirm the correct binary property name is selected
Example fix
// before — [{"text": "..."}, {"text": "..."}]\n (JSON array)
// after — {"text": "..."}\n{"text": "..."}\n (JSONL, one object per line) 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.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')) {
// Convert the file to JSONL and retry
const converted = convertToJsonl(fileContent);
await uploadJsonlString(this, i, converted);
}
throw error;
} Prevention
- Validate JSONL format before uploading — each line must be a standalone JSON object
- Never wrap data in a JSON array; use one object per line
- Use jq to convert: cat data.json | jq -c '.[]' > data.jsonl
- Test with a small sample file first
When it happens
Trigger: A file uploaded with purpose 'fine-tune' is not in JSONL format. The OpenAI API validates the file server-side and returns a 400 with a description mentioning JSONL format. 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 a CSV or plain text file for fine-tuning; malformed JSONL with invalid JSON on some lines; wrong file selected in the node.
Related errors
- The file content is not in JSONL format
- An assistant with the same name '${name}' already exists
- The maximum number of files that can be attached to the assi
- ${error.message}
- Invalid file_ids type
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/1607f5d6cd3bf4dc.
Report an issue: GitHub.