GoogleChrome/lighthouse · error

[${err.message}] Did not find the expected syntax in message

Error message

[${err.message}] Did not find the expected syntax in message: ${err.originalMessage}

What it means

Thrown by _lhlValidityChecks() when the ICU MessageParser (from intl-messageformat) raises a SyntaxError while parsing an LHL message string. This means the message contains malformed ICU syntax — unbalanced braces, stray characters, or invalid placeholder/argument constructs that the parser cannot tokenize.

Source

Thrown at core/scripts/i18n/collect-strings.js:200

  _ctcValidityChecks(ctc);

  return ctc;
}

/**
 * Do some basic checks on an lhl message to confirm that it is valid. Future
 * lhl regression catching should go here.
 *
 * @param {string} lhlMessage
 */
function _lhlValidityChecks(lhlMessage) {
  let parsedMessageElements;
  try {
    parsedMessageElements = MessageParser.parse(escapeIcuMessage(lhlMessage), {ignoreTag: true});
  } catch (err) {
    if (err.name !== 'SyntaxError') throw err;
    throw new Error(`[${err.message}] Did not find the expected syntax in message: ${err.originalMessage}`);
  }

  /**
   * @param {MessageParser.MessageFormatElement[]} elements
   */
  function validate(elements) {
    for (const element of elements) {
      if (element.type === MessageParser.TYPE.plural || element.type === MessageParser.TYPE.select) {
        // `plural`/`select` arguments can't have content before or after them.
        // See http://userguide.icu-project.org/formatparse/messages#TOC-Complex-Argument-Types
        // e.g. https://github.com/GoogleChrome/lighthouse/pull/11068#discussion_r451682796
        if (elements.length > 1) {
          throw new Error(`Content cannot appear outside plural or select ICU messages. Instead, repeat that content in each option (message: '${lhlMessage}')`);
        }

        for (const option of Object.values(element.options)) {
          validate(option.value);
        }

View on GitHub (pinned to 9515cd4e58)

Solutions

  1. Locate the message identified in the error (err.originalMessage is printed) and fix the ICU syntax — balance all braces and escape literal braces with single quotes per ICU rules.
  2. If a literal `{` or `}` is needed in output, use single-quote escaping: `'{'` and `'}'`.
  3. Validate the message with a local ICU MessageFormat parser before committing.

Example fix

// before
message: 'Use { or } literally'
// after
message: "Use '{' or '}' literally"
Defensive patterns

Strategy: try-catch

Validate before calling

const {parse} = require('intl-messageformat');
function isValidIcu(msg) {
  try { parse(msg, {ignoreTag: true}); return true; } catch { return false; }
}

Try / catch

try {
  _lhlValidityChecks(lhlMessage);
} catch (e) {
  console.error(`Invalid ICU message in ${key}: ${lhlMessage}`);
  throw e;
}

Prevention

When it happens

Trigger: Adding a UIStrings message with unbalanced `{`, `}`, a malformed plural/select argument, or stray ICU metacharacters that are not valid placeholders, then running collect-strings.

Common situations: Messages containing literal curly braces for display (not as ICU placeholders); copy-pasted content with special ICU characters like `#` outside plural options; hand-editing messages without escaping.

Related errors


AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13). Data as JSON: /api/errors/6bb71d4b96f10f91. Report an issue: GitHub.