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.

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 '")      ; #2

View on GitHub (pinned to e815e74d4c)

Solutions

  1. 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).
  2. Identify the culprit from the message: it prints the regex literally (e.g. /foo/g), so search your handler file for that pattern.
  3. 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

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.