{"record":{"id":"405aed8d2397881f","repo":"GoogleChrome/lighthouse","slug":"must-use-same-format-and-formattype-for-a-given-na","errorCode":null,"errorMessage":"must use same format and formatType for a given name. Invalid for: ${rawName}","messagePattern":"must use same format and formatType for a given name\\. Invalid for: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/scripts/i18n/collect-strings.js","lineNumber":346,"sourceCode":"    icu.message += preambleText;\n\n    if (!rawName || !format || !formatType) continue;\n    // Check that custom-formatted ICU not using non-supported format ex:\n    // * using a second arg anything other than \"number\"\n    // * using a third arg that is not millis, secs, bytes, %, or extended %\n    if (!format.match(/^number$/)) {\n      throw Error(`Unsupported custom-formatted ICU format var \"${format}\" in message \"${icu.message}\"`);\n    }\n    if (!formatType.match(/milliseconds|seconds|bytes|percent|extendedPercent/)) {\n      throw Error(`Unsupported custom-formatted ICU type var \"${formatType}\" in message \"${icu.message}\"`);\n    }\n\n    let index;\n    const previousRawName = rawNameCache.get(rawName);\n    if (previousRawName) {\n      const [prevFormat, prevFormatType, prevIndex] = previousRawName;\n      if (prevFormat !== format || prevFormatType !== formatType) {\n        throw new Error(`must use same format and formatType for a given name. Invalid for: ${rawName}`);\n      }\n\n      index = prevIndex;\n    } else {\n      index = idx++;\n      rawNameCache.set(rawName, [format, formatType, index]);\n    }\n\n    // Append ICU replacements if there are any.\n    const placeholderName = `CUSTOM_ICU_${index}`;\n    icu.message += `$${placeholderName}$`;\n    let example;\n\n    // Make some good examples.\n    switch (formatType) {\n      case 'seconds':\n        example = '2.4';\n        break;","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/scripts/i18n/collect-strings.js#L328-L364","documentation":"Thrown during CTC conversion when the same placeholder rawName is used more than once in a message but with a different `format` or `formatType` (e.g. `{timeInMs, number, milliseconds}` vs `{timeInMs, number, seconds}`). The pipeline requires that a given placeholder name always maps to the same custom format so the generated CUSTOM_ICU_N placeholder is unambiguous.","triggerScenarios":"Using the same ICU placeholder name with two different custom format annotations within the same message or across messages that share a name in the same conversion pass.","commonSituations":"Copy-pasting a placeholder for a different unit (bytes vs milliseconds) and forgetting to rename; refactoring that changes a format type in one place but not another.","solutions":["Rename one of the conflicting placeholders so each name maps to exactly one format/formatType pair.","Align both usages to the same format and formatType.","Search the message string for the rawName and reconcile all occurrences."],"exampleFix":"// before\nmessage: '{timeInMs, number, milliseconds} ms ({timeInMs, number, seconds})'\n// after\nmessage: '{timeInMs, number, milliseconds} ms ({timeInSec, number, seconds})'","handlingStrategy":"validation","validationCode":"function checkPlaceholderFormatConsistency(message) {\n  const re = /\\{(?<name>\\w+),\\s*number,\\s*(?<format>\\w+)\\}/g;\n  const seen = new Map();\n  let m;\n  while ((m = re.exec(message))) {\n    if (seen.has(m.groups.name) && seen.get(m.groups.name) !== m.groups.format) {\n      return false;\n    }\n    seen.set(m.groups.name, m.groups.format);\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use distinct placeholder names per format type (timeInMs vs timeInSec).","Audit all ICU placeholders in a message for format consistency before committing.","Document the allowed format types: milliseconds, seconds, bytes, percent, extendedPercent."],"tags":["i18n","icu","placeholder","format","collect-strings"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}