GoogleChrome/lighthouse · error
unsupported JSDoc comment: ${JSON.stringify(comment)}
Error message
unsupported JSDoc comment: ${JSON.stringify(comment)} What it means
Thrown by coerceToSingleLineAndTrim() when a JSDoc comment value passed from the TypeScript compiler API is not a string. Per TS PR #41877, JSDoc comments can theoretically be string | string[] | undefined, but this i18n collection script currently only handles the string form. If a future TypeScript version starts returning array/structured comments for certain JSDoc constructs, this guard fires.
Source
Thrown at core/scripts/i18n/collect-strings.js:112
if (ast.comment) {
// The entire comment is the description, so return everything.
return {description: coerceToSingleLineAndTrim(ast.comment), examples: {}};
}
throw Error(`Missing description comment for message "${message}"`);
}
/**
* Collapses a jsdoc comment into a single line and trims whitespace.
* @param {import('typescript').JSDoc['comment']} comment
* @return {string}
*/
function coerceToSingleLineAndTrim(comment = '') {
// The non-string types were introduced in https://github.com/microsoft/TypeScript/pull/41877
// Not currently used, but utility `getTextOfJSDocComment` will convert if the types switch over.
if (typeof comment !== 'string') {
throw new Error(`unsupported JSDoc comment: ${JSON.stringify(comment)}`);
}
// Line breaks within a jsdoc comment should always be replaceable with a space.
return comment.replace(/\n+/g, ' ').trim();
}
/**
* Parses a string of the form `{exampleValue} placeholderName`, parsed by tsc
* as the content of an `@example` tag.
* @param {string} rawExample
* @return {{placeholderName: string, exampleValue: string}}
*/
function parseExampleJsDoc(rawExample) {
const match = rawExample.match(/^{(?<exampleValue>[^}]+)} (?<placeholderName>.+)$/);
if (!match || !match.groups) throw new Error(`Incorrectly formatted @example: "${rawExample}"`);
const {placeholderName, exampleValue} = match.groups;
return {placeholderName, exampleValue};
}View on GitHub (pinned to 9515cd4e58)
Solutions
- Pin or downgrade TypeScript to the version the project currently uses (check package.json / devDependencies).
- If upgrading intentionally, update coerceToSingleLineAndTrim to handle string[] by joining elements, mirroring TS utility getTextOfJSDocComment.
- Inspect the offending JSDoc block in the source file reported upstream and simplify it to a plain single-line comment.
Example fix
// before
if (typeof comment !== 'string') {
throw new Error(`unsupported JSDoc comment: ${JSON.stringify(comment)}`);
}
// after
if (Array.isArray(comment)) {
comment = comment.map(c => typeof c === 'string' ? c : c.text).join(' ');
}
if (typeof comment !== 'string') {
throw new Error(`unsupported JSDoc comment: ${JSON.stringify(comment)}`);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Before calling coerceToSingleLineAndTrim, normalize the comment:
function normalizeJSDocComment(comment) {
if (Array.isArray(comment)) return comment.map(c => typeof c === 'string' ? c : c.text).join(' ');
if (typeof comment === 'object' && comment !== null && 'text' in comment) return comment.text;
if (typeof comment === 'string') return comment;
return '';
} Type guard
/** @param {unknown} c @returns {c is string} */
function isStringComment(c) { return typeof c === 'string'; } Try / catch
try {
return coerceToSingleLineAndTrim(jsdoc.comment);
} catch (e) {
if (/unsupported JSDoc comment/.test(e.message)) return '';
throw e;
} Prevention
- Pin the TypeScript version in devDependencies to avoid JSDoc node-shape changes.
- Write JSDoc descriptions as simple single-line strings.
- If upgrading TypeScript, run collect-strings in CI to catch regressions early.
When it happens
Trigger: Running `node core/scripts/i18n/collect-strings.js` after upgrading TypeScript, or authoring a JSDoc annotation that TypeScript parses into a non-string comment node (e.g. multi-part structured comments introduced by a newer TS API).
Common situations: TypeScript major-version bumps that change the JSDoc comment node shape; exotic JSDoc tags or inline link structures that tsc represents as arrays rather than plain strings.
Related errors
- Incorrectly formatted @example: "${rawExample}"
- [${err.message}] Did not find the expected syntax in message
- Content cannot appear outside plural or select ICU messages.
- must use same format and formatType for a given name. Invali
- Ctc messages cannot contain double dollar: ${icu.message}
AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13).
Data as JSON: /api/errors/5a9bd8f72abb7be3.
Report an issue: GitHub.