GoogleChrome/lighthouse · error
unexpected response: ${response.statusCode} ${response.statu
Error message
unexpected response: ${response.statusCode} ${response.statusText} What it means
Thrown inside the WPT test-polling loop when the response statusCode falls outside the expected set (1xx running, and the success/completion codes handled above). This catches any WPT polling response that isn't recognized as 'running', 'complete', or 'error', indicating an unexpected WPT state.
Source
Thrown at core/scripts/lantern/collect/collect.js:143
const responseJson = await fetchString(jsonUrl);
const response = JSON.parse(responseJson);
if (response.statusCode === 200) {
lhr = response.data.lighthouse;
assertLhr(lhr);
break;
}
if (response.statusCode >= 100 && response.statusCode < 200) {
// If behindCount doesn't exist, the test is currently running.
// * Wait 30 seconds if the test is currently running.
// * Wait an additional 10 seconds for every test ahead of this one.
// * Don't wait for more than 10 minutes.
const secondsToWait = Math.min(30 + 10 * (response.data.behindCount || 0), 10 * 1000);
if (DEBUG) log.log('poll wpt in', secondsToWait);
await new Promise((resolve) => setTimeout(resolve, secondsToWait * 1000));
} else {
throw new Error(`unexpected response: ${response.statusCode} ${response.statusText}`);
}
}
const traceUrl = new URL('/getgzip.php', WPT_URL);
traceUrl.searchParams.set('test', testId);
traceUrl.searchParams.set('file', 'lighthouse_trace.json');
const traceJson = await fetchString(traceUrl.href);
/** @type {LH.Trace} */
const trace = JSON.parse(traceJson);
// For some reason, the first trace event is an empty object.
trace.traceEvents = trace.traceEvents.filter(e => Object.keys(e).length > 0);
return {
lhr: JSON.stringify(lhr),
trace: JSON.stringify(trace),
};
}View on GitHub (pinned to 9515cd4e58)
Solutions
- Inspect the statusCode and statusText in the error to identify the unknown WPT state.
- If transient, retry the collection after a wait.
- If WPT changed its API, update the polling switch/case to handle the new status.
Defensive patterns
Strategy: try-catch
Validate before calling
const EXPECTED_WPT_STATUSES = new Set([100, 101, 200, 400, 500]);
function isExpectedWptPollStatus(statusCode) {
return EXPECTED_WPT_STATUSES.has(statusCode);
} Try / catch
try {
await pollTestUntilComplete(testId);
} catch (e) {
if (/unexpected response/.test(e.message)) {
console.warn(`WPT polling returned unknown status, retrying: ${e.message}`);
}
throw e;
} Prevention
- Log the full WPT polling response when status codes are unexpected.
- Retry transient WPT server errors before failing.
- Update the polling state machine when WPT introduces new status codes.
When it happens
Trigger: WPT returns a polling response with an unexpected statusCode (e.g. a new status type, or a server error mid-test) that the polling logic doesn't have a branch for.
Common situations: WPT API changes introducing new status codes; transient WPT server errors; test cancelled or invalidated server-side.
Related errors
- unexpected status code ${wptResponse.statusCode} ${wptRespon
- error fetching ${url}: ${response.status} ${response.statusT
- missing WPT_KEY
- runtime error: ${lhr.runtimeError}
- Invalid precomputed lantern data file
AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13).
Data as JSON: /api/errors/206df2b57bdce030.
Report an issue: GitHub.