gchq/CyberChef · error · OperationError
Unable to parse JSON to CSV: ${err.toString()}
Error message
Unable to parse JSON to CSV: ${err.toString()} What it means
Thrown by JSON to CSV after BOTH conversion attempts fail: the primary toCSV() and a fallback that flattens the structure and retries. The error captures whichever exception the fallback path raised (flatten() or toCSV(true)), reported via err.toString().
Source
Thrown at src/core/operations/JSONToCSV.mjs:104
// Record values so they don't have to be passed to other functions explicitly
this.cellDelim = cellDelim;
this.rowDelim = rowDelim;
this.flattened = input;
if (!(this.flattened instanceof Array)) {
this.flattened = [input];
}
try {
return this.toCSV();
} catch (err) {
try {
this.flattened = flatten(input);
if (!(this.flattened instanceof Array)) {
this.flattened = [this.flattened];
}
return this.toCSV(true);
} catch (err) {
throw new OperationError("Unable to parse JSON to CSV: " + err.toString());
}
}
}
/**
* Correctly escapes a cell's contents based on the cell and row delimiters.
*
* @param {string} data
* @param {boolean} force - Whether to force conversion of data to fit in a cell
* @returns {string}
*/
escapeCellContents(data, force=false) {
if (data !== "string") {
const isPrimitive = data == null || typeof data !== "object";
if (isPrimitive) data = `${data}`;
else if (force) data = JSON.stringify(data);
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Pre-shape the input into an array of flat, uniformly-keyed objects.
- Use JQ or JSONata upstream to project only scalar fields before conversion.
- Remove or stringify nested values so flattening produces leaf scalars.
- Confirm the input is actually JSON (not CSV/TSV) before this operation.
Example fix
// before: nested object that cannot be tabulated
chef.JSONToCSV({ user: { name: 'Ann', addr: { city: 'X' } } });
// after: flatten to scalar fields first
chef.JSONToCSV([{ name: 'Ann', city: 'X' }]); Defensive patterns
Strategy: validation
Validate before calling
function normaliseForCsv(parsed) {
const arr = Array.isArray(parsed) ? parsed : [parsed];
return arr.map(o =>
Object.fromEntries(Object.entries(o).map(([k, v]) =>
[k, (v !== null && typeof v === 'object') ? JSON.stringify(v) : v]))
);
} Type guard
function isTabulatable(parsed) {
const arr = Array.isArray(parsed) ? parsed : [parsed];
return arr.every(o => o && typeof o === 'object' &&
Object.values(o).every(v => v === null || typeof v !== 'object'));
} Try / catch
try {
return chef.JSONToCSV(input);
} catch (e) {
if (/Unable to parse JSON to CSV/.test(e.message))
throw new Error('Flatten the JSON to an array of scalar-field records first');
throw e;
} Prevention
- Project nested objects to flat scalar fields before converting.
- Use JQ/JSONata upstream to select uniform keys.
- Stringify any remaining nested leaves.
When it happens
Trigger: Input JSON that is neither a flat record nor an array of flat records, where flattening still yields something toCSV cannot serialise: a scalar primitive at the top level, a structure with circular references, or a record whose flattened cells still contain nested objects/arrays the formatter rejects.
Common situations: Trying to convert a single nested object or a deeply-nested/ragged array of objects. Passing already-CSV text by mistake. Objects containing mixed array/object leaf values that do not flatten cleanly.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unable to parse CSV: ${err}
- Unable to stringify YAML: ${err}
- Invalid jq expression: ${err.message}
- Invalid Jsonata Expression: ${err.message}
- Could not encode JSON to MessagePack: ${err}
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/229a3c85e89736cb.
Report an issue: GitHub.