GoogleChrome/lighthouse · error · Error
Invalid value: Argument 'extra-headers' must be a string
Error message
Invalid value: Argument 'extra-headers' must be a string
What it means
The --extra-headers flag accepts either a JSON object string (inline) or a path to a JSON file. coerceExtraHeaders first allows undefined and object types, then requires any remaining value to be a string (which is then parsed as JSON or read from a file path). This error fires when the value is a type other than undefined, object, or string — e.g., a number or boolean.
Source
Thrown at cli/cli-flags.js:447
function coerceLocale(value) {
if (value === undefined) return;
if (typeof value !== 'string') throw new Error(`Invalid value: Argument 'locale' must be a string`);
return /** @type {LH.Locale} */ (value);
}
/**
* `--extra-headers` comes in as a JSON string or a path to a JSON string, but the flag value
* needs to be the parsed object. Load file (if necessary) and returns the parsed object.
* @param {unknown} value
* @return {LH.SharedFlagsSettings['extraHeaders']}
*/
function coerceExtraHeaders(value) {
// TODO: this function does not actually verify the object type.
if (value === undefined) return value;
if (typeof value === 'object') return /** @type {LH.SharedFlagsSettings['extraHeaders']} */ (value);
if (typeof value !== 'string') {
throw new Error(`Invalid value: Argument 'extra-headers' must be a string`);
}
// (possibly) load and parse extra headers from JSON.
if (!value.startsWith('{')) {
// If not a JSON object, assume it's a path to a JSON file.
return JSON.parse(fs.readFileSync(value, 'utf-8'));
}
return JSON.parse(value);
}
/**
* Take yarg's unchecked object value and ensure it's proper throttling settings.
* @param {unknown} value
* @return {LH.ThrottlingSettings|undefined}
*/
function coerceThrottling(value) {
if (value === undefined) return;
View on GitHub (pinned to 9515cd4e58)
Solutions
- Pass extra headers as an inline JSON string: --extra-headers='{"Authorization":"Bearer token"}'
- Pass a path to a JSON file: --extra-headers=./headers.json
- When using the programmatic API, pass the parsed object directly in flags: {extraHeaders: {Authorization: 'Bearer token'}}
Example fix
# before
lighthouse --extra-headers=12345 https://example.com
# after
lighthouse --extra-headers='{"X-Custom-Header":"value"}' https://example.com Defensive patterns
Strategy: validation
Validate before calling
// Validate extra-headers before passing to Lighthouse
function validateExtraHeaders(value) {
if (value === undefined) return;
if (typeof value === 'object') return; // already parsed object
if (typeof value !== 'string') {
throw new Error('--extra-headers must be a JSON string or file path');
}
// Optionally pre-validate JSON
if (value.startsWith('{')) JSON.parse(value);
} Type guard
/** @param {unknown} v */
function isExtraHeadersValue(v) {
return v === undefined || typeof v === 'object' || typeof v === 'string';
} Prevention
- Pass extra headers as a JSON object string: --extra-headers='{"key":"value"}'
- Alternatively point to a JSON file: --extra-headers=./headers.json
- In the programmatic API, pass the parsed object directly: {extraHeaders: {key: 'value'}}
When it happens
Trigger: Passing --extra-headers with a value that yargs resolves to neither undefined, an object, nor a string. For example, a numeric value or a boolean that bypasses yargs's own type handling and reaches the coerce function.
Common situations: Programmatic yargs usage passing a non-string/non-object value; unusual flag syntax causing type coercion issues; shell quoting edge cases that produce unexpected types.
Related errors
- Please provide a url
- Invalid value: Argument must be a string or a boolean
- Invalid values. Argument 'output' must be an array from choi
- "${str}" is not a valid 'output' value. Argument 'output' mu
- --output-path (${value}) cannot be written to
AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13).
Data as JSON: /api/errors/f440b180961a66f2.
Report an issue: GitHub.