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

  1. Simplify or modernise the toolchain: update escodegen/espree to a version supporting the syntax.
  2. Strip the unsupported syntax before beautifying.
  3. Replace the '<br>' with a newline so the message reads correctly in non-HTML contexts.
  4. 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

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

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/73c9186ec1e32354. Report an issue: GitHub.