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

  1. Inspect the statusCode and statusText in the error to identify the unknown WPT state.
  2. If transient, retry the collection after a wait.
  3. 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

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


AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13). Data as JSON: /api/errors/206df2b57bdce030. Report an issue: GitHub.