GoogleChrome/lighthouse · error
UIStrings exported but no definition found: ${relativeToRoot
Error message
UIStrings exported but no definition found: ${relativeToRootPath} What it means
Thrown during collection when a module exports `UIStrings` (or `default.UIStrings`) at runtime, but the UISTRINGS_REGEX pattern cannot find a matching definition in the raw file text. This means the export exists dynamically but the static text-based parser cannot locate the definition to extract messages.
Source
Thrown at core/scripts/i18n/collect-strings.js:582
const files = glob.sync(globPattern, {
cwd: LH_ROOT,
ignore: ignoredPathComponents,
});
for (const relativeToRootPath of files) {
const absolutePath = path.join(LH_ROOT, relativeToRootPath);
if (!process.env.CI) console.log('Collecting from', relativeToRootPath);
const content = fs.readFileSync(absolutePath, 'utf8');
const exportVars = await import(pathToFileURL(absolutePath).href);
const regexMatch = content.match(UISTRINGS_REGEX);
const exportedUIStrings = exportVars.UIStrings || exportVars.default?.UIStrings;
if (!regexMatch) {
// No UIStrings found in the file text or exports, so move to the next.
if (!exportedUIStrings) continue;
throw new Error('UIStrings exported but no definition found: ' + relativeToRootPath);
}
if (!exportedUIStrings) {
throw new Error('UIStrings defined in file but not exported');
}
// just parse the UIStrings substring to avoid ES version issues, save time, etc
const justUIStrings = 'const ' + regexMatch[0];
const parsedMessages = parseUIStrings(justUIStrings, exportedUIStrings);
for (const [key, parsed] of Object.entries(parsedMessages)) {
const {message, description, examples} = parsed;
const converted = convertMessageToCtc(message, examples);
// Don't include placeholders if there are none.
const placeholders = Object.keys(converted.placeholders).length === 0 ?
undefined :
converted.placeholders;View on GitHub (pinned to 9515cd4e58)
Solutions
- Define UIStrings as a top-level `const UIStrings = {...}` literal in the same file that exports it.
- Ensure the export uses `export const UIStrings` or `export {UIStrings}` referencing a directly-defined const matching UISTRINGS_REGEX.
- Avoid re-exporting UIStrings from another module in files scanned by collect-strings.
Example fix
// before
export {UIStrings} from './strings.js'
// after
const UIStrings = {
/** @description My message */
myMessage: 'My message',
};
export {UIStrings}; Defensive patterns
Strategy: validation
Validate before calling
const UISTRINGS_REGEX = /(?:const|let|var)\s+UIStrings\s*=\s*\{/;
function hasInlineUIStringsDefinition(fileText) {
return UISTRINGS_REGEX.test(fileText);
} Prevention
- Define UIStrings as a top-level const literal in the same file that exports it.
- Avoid re-exporting UIStrings from another module.
- Use the standard `const UIStrings = {...}; export {UIStrings};` pattern.
When it happens
Trigger: Exporting UIStrings via a computed property, re-export from another module, dynamic spread, or any pattern that defeats the simple regex-based text scan — e.g. `export {UIStrings} from './other'` or `module.exports.UIStrings`.
Common situations: Refactoring how UIStrings is exported; using re-exports instead of inline definitions; CommonJS-style exports in a file the scanner expects ESM from.
Related errors
- UIStrings defined in file but not exported
- unsupported JSDoc comment: ${JSON.stringify(comment)}
- Incorrectly formatted @example: "${rawExample}"
- [${err.message}] Did not find the expected syntax in message
- Content cannot appear outside plural or select ICU messages.
AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13).
Data as JSON: /api/errors/3739e3cea719bce9.
Report an issue: GitHub.