gchq/CyberChef · error · OperationError
Unable to parse JavaScript.<br>${e.message}
Error message
Unable to parse JavaScript.<br>${e.message} What it means
Thrown by JavaScript Beautify when escodegen cannot generate code from the parsed AST. The input was parsed (espree) but code generation fails, e.g. on AST nodes escodegen does not support. Note the message injects a literal '<br>' HTML tag into the text, which renders as raw characters outside an HTML context.
Source
Thrown at src/core/operations/JavaScriptBeautify.mjs:88
const options = {
format: {
indent: {
style: beautifyIndent
},
quotes: quotes,
semicolons: beautifySemicolons,
},
comment: beautifyComment
};
if (options.comment)
AST = escodegen.attachComments(AST, AST.comments, AST.tokens);
result = escodegen.generate(AST, options);
} catch (e) {
// Leave original error so the user can see the detail
throw new OperationError("Unable to parse JavaScript.<br>" + e.message);
}
return result;
}
}
export default JavaScriptBeautify;
View on GitHub (pinned to 4290ea7539)
Solutions
- Simplify or modernise the toolchain: update escodegen/espree to a version supporting the syntax.
- Strip the unsupported syntax before beautifying.
- Replace the '<br>' with a newline so the message reads correctly in non-HTML contexts.
- Use a different formatter (e.g. terser/prettier) for unsupported constructs.
Example fix
// before: HTML break tag in a plain-text error message
throw new OperationError("Unable to parse JavaScript.<br>" + e.message);
// after: newline, readable everywhere
throw new OperationError(`Unable to parse JavaScript.\n${e.message}`); Defensive patterns
Strategy: try-catch
Validate before calling
function canParseJs(src) {
try { espree.parse(src, { ecmaVersion: 'latest' }); return true; }
catch (e) { throw new Error(`JS parse failed: ${e.message}`); }
} Type guard
function isParsableJs(src) {
try { espree.parse(String(src), { ecmaVersion: 'latest' }); return true; } catch { return false; }
} Try / catch
try {
return chef.JavaScriptBeautify(input);
} catch (e) {
if (/Unable to parse JavaScript/.test(e.message))
throw new Error('Source has syntax escodegen cannot emit - simplify or upgrade the toolchain');
throw e;
} Prevention
- Update espree/escodegen to support modern syntax.
- Strip unsupported constructs before beautifying.
- Replace the '<br>' with a newline so messages read in non-HTML contexts.
When it happens
Trigger: Source using newer syntax the bundled escodegen cannot emit (e.g. certain optional chaining/nullish-coalescing/private-fields forms in older builds), an AST hand-constructed incorrectly, or a parser/escodegen version mismatch. Syntax that espree parses loosely but escodegen rejects.
Common situations: Beautifying modern JS (ES2020+) on an older bundled toolchain. Mixing parser plugins. Files with experimental syntax flags. The '<br>' leaking into CLI/Node output as literal text.
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
- Error minifying JavaScript. (${result.error})
- Schema ${error}
- Invalid input JSON: ${err.message}
- Unable to parse input as JSON.\n${err}
- ${err}
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/73c9186ec1e32354.
Report an issue: GitHub.