GoogleChrome/lighthouse · error

run failed to get metrics

Error message

run failed to get metrics

What it means

Thrown by assertLhr() in the Lantern data-collection script after a Lighthouse run completes. It validates that the returned Lighthouse Result (lhr) contains all required timing metrics: firstContentfulPaint, interactive (TTI), maxPotentialFID, and speedIndex. The script collects traces and metrics from real sites to build Lantern's accuracy baseline, so an lhr missing these core metrics is unusable.

Source

Thrown at core/scripts/lantern/collect/collect.js:198

  return {result: null, retries: maxAttempts - 1, errors};
}

/**
 * @param {LH.Result=} lhr
 */
function assertLhr(lhr) {
  if (!lhr) throw new Error('missing lhr');
  if (lhr.runtimeError) throw new Error(`runtime error: ${lhr.runtimeError}`);
  const metrics = common.getMetrics(lhr);
  if (metrics?.firstContentfulPaint &&
      metrics.interactive &&
      // WPT won't have this, we'll just get from the trace.
      // metrics.largestContentfulPaint &&
      metrics.maxPotentialFID &&
      metrics.speedIndex
  ) return;
  throw new Error('run failed to get metrics');
}

async function main() {
  // Resume state from previous invocation of script.
  summary = common.loadSummary();

  // Remove data if no longer in TEST_URLS.
  summary.results = summary.results
    .filter(urlSet => TEST_URLS.includes(urlSet.url));

  fs.mkdirSync(common.collectFolder, {recursive: true});

  // Traces are collected for one URL at a time, in series, so all traces are from a small time
  // frame, reducing the chance of a site change affecting results.
  for (const url of TEST_URLS) {
    // This URL has been done on a previous script invocation. Skip it.
    if (summary.results.find((urlResultSet) => urlResultSet.url === url)) {
      log.log(`already collected traces for ${url}`);

View on GitHub (pinned to 9515cd4e58)

Solutions

  1. Re-run the collection — collect.js already retries up to 3 times via repeatUntilPassOrNull (line 169); if all 3 fail, the URL is recorded with null result and the script continues
  2. Check the lhr.runtimeError field (captured at line 189) for page-level errors that precede this throw
  3. Verify the target URL is reachable and loads normally in a browser with Chrome DevTools open
  4. Ensure your Chrome and Lighthouse versions are compatible — metric computation can regress across major versions
  5. If using WPT (TEST_URLS with WPT_KEY set), verify WPT ran Lighthouse successfully by inspecting the WPT JSON response directly
Defensive patterns

Strategy: retry

Try / catch

// collect.js already wraps in repeatUntilPassOrNull (3 retries).
// In your own collection code:
const {result, errors} = await repeatUntilPassOrNull(
  () => runUnthrottledLocally(url), 3
);
if (!result) {
  console.error(`All retries failed for ${url}:`, errors);
  continue;
}

Prevention

When it happens

Trigger: Called from runUnthrottledLocally() (collect.js:104) after a local `node cli <url>` run, and from runForWpt() (collect.js:130) after polling WebPageTest for results. Fires when common.getMetrics(lhr) returns undefined or an object missing one of the four required metric fields. The runtimeError check at line 189 fires first for page-level errors, so this specific throw means the page loaded but metric computation produced incomplete results.

Common situations: Target page is a slow SPA that never reaches Time To Interactive within the run timeout. Chrome crashed or was killed mid-run, producing a partial trace. A Lighthouse version regression broke metric computation (e.g., TTI observer). WPT returned a partial lhr with missing audits. The page redirected to an error page that loads instantly but has no meaningful content metrics.

Related errors


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