dianping/cat · error · Error
{regex}
Error message
{regex} What it means
google-code-prettify's combinePrefixPatterns builds one master RegExp from a language handler's list of token regexes; it refuses regexes carrying the global (/g) or multiline (/m) flags because it rewrites each pattern's source and renumbers capture groups — flags on the parts would change matching semantics once joined. The thrown Error's message is simply the offending regex's string form, which identifies which pattern caused it.
Solutions
- Remove the g and m flags from every regex in the language handler's pattern lists — they are meaningless there (the combined regex is applied manually with exec in a loop).
- Identify the culprit from the message: it prints the regex literally (e.g. /foo/g), so search your handler file for that pattern.
- If multiline behavior is needed, express it with (^|[^\n]) constructs or [\s\S] instead of the m flag; matching is already done line-aware by the caller.
Example fix
// before var patterns = [ [PR.PR_STRING, /"[^"]*"/g, /'[^']*'/g] ]; PR.registerLangHandler(PR.createSimpleLexer([], patterns), ['mylang']); // after var patterns = [ [PR.PR_STRING, /"[^"]*"/, /'[^']*'/] ]; PR.registerLangHandler(PR.createSimpleLexer([], patterns), ['mylang']);
Defensive patterns
Strategy: try-catch
Validate before calling
// before registering a handler, strip offending flags is not possible (flags are
// immutable), so validate the source patterns at authoring time:
function assertPrettifySafe(regexs) {
regexs.forEach(function (r) {
if (r.global || r.multiline) throw new Error('remove /g or /m from: ' + r);
});
} Type guard
function isPrettifySafeRegex(r) {
return r instanceof RegExp && !r.global && !r.multiline;
} Try / catch
try {
prettyPrint();
} catch (e) {
if (/^\/.+\/[gmi]*[gm]/.test(e.message) || e instanceof Error && String(e.message).indexOf('/') === 0) {
console.warn('prettify handler has flagged regex:', e.message);
} else throw e;
} Prevention
- Never reuse application regexes with /g in language handlers
- Test custom lang handlers by prettifying a sample snippet at load time
- Keep custom handler patterns flag-free: no g, no m
When it happens
Trigger: Registering or shipping a language handler (PR.registerLangHandler) whose fallthrough/style patterns include a regex declared with /g or /m, e.g. [PR.PR_STRING, /"[^"]*"/g]. Then prettifying any code block triggers combinePrefixPatterns and this throw.
Common situations: Copy-pasting a regex from application code (where /g was needed for exec loops) into a custom prettify language handler; upgrading a custom lang-*.js written against a different prettify version; hand-writing a syntax highlighter plugin for the editor's code viewer.
Related errors
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/d390fd0a5f7dca39.
Report an issue: GitHub.
Appendix: source
Thrown at cat-home/src/main/webapp/assets/js/prettify.js:475
} else if (ch0 !== '\\') {
// TODO: handle letters in numeric escapes.
parts[i] = p.replace(
/[a-zA-Z]/g,
function (ch) {
var cc = ch.charCodeAt(0);
return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
});
}
}
}
return parts.join('');
}
var rewritten = [];
for (var i = 0, n = regexs.length; i < n; ++i) {
var regex = regexs[i];
if (regex.global || regex.multiline) { throw new Error('' + regex); }
rewritten.push(
'(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
}
return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
}
/**
* Split markup into a string of source code and an array mapping ranges in
* that string to the text nodes in which they appear.
*
* <p>
* The HTML DOM structure:</p>
* <pre>
* (Element "p"
* (Element "b"
* (Text "print ")) ; #1
* (Text "'Hello '") ; #2View on GitHub (pinned to e815e74d4c)