{"record":{"id":"b6876e85cf7b1a0a","repo":"GoogleChrome/lighthouse","slug":"runtime-error-lhr-runtimeerror","errorCode":null,"errorMessage":"runtime error: ${lhr.runtimeError}","messagePattern":"runtime error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/scripts/lantern/collect/collect.js","lineNumber":189,"sourceCode":"\n  for (let i = 0; i < maxAttempts; i++) {\n    try {\n      return {result: await asyncFn(), retries: i, errors};\n    } catch (err) {\n      log.log('Error: ' + err.toString());\n      errors.push(err.toString());\n    }\n  }\n\n  return {result: null, retries: maxAttempts - 1, errors};\n}\n\n/**\n * @param {LH.Result=} lhr\n */\nfunction assertLhr(lhr) {\n  if (!lhr) throw new Error('missing lhr');\n  if (lhr.runtimeError) throw new Error(`runtime error: ${lhr.runtimeError}`);\n  const metrics = common.getMetrics(lhr);\n  if (metrics?.firstContentfulPaint &&\n      metrics.interactive &&\n      // WPT won't have this, we'll just get from the trace.\n      // metrics.largestContentfulPaint &&\n      metrics.maxPotentialFID &&\n      metrics.speedIndex\n  ) return;\n  throw new Error('run failed to get metrics');\n}\n\nasync function main() {\n  // Resume state from previous invocation of script.\n  summary = common.loadSummary();\n\n  // Remove data if no longer in TEST_URLS.\n  summary.results = summary.results\n    .filter(urlSet => TEST_URLS.includes(urlSet.url));","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/scripts/lantern/collect/collect.js#L171-L207","documentation":"Thrown by assertLhr() when the Lighthouse Result object has a non-null/non-empty `runtimeError` property. This means Lighthouse itself encountered a runtime failure during the run (e.g. page load error, navigation timeout, protocol error) even though a result object was returned. The script refuses to treat a runtime-errored run as valid for metric comparison.","triggerScenarios":"Collecting Lantern metrics via WPT where the Lighthouse run completed but recorded a runtimeError — page failed to load, connection reset, or a DevTools protocol disconnect.","commonSituations":"Target URL is down or extremely slow; WPT agent environment issues; browser/Chrome version incompatibility; network errors during the audit.","solutions":["Check lhr.runtimeError code/message (printed in the error) for the specific failure reason.","Retry the collection — many runtime errors are transient (navigation timeouts, protocol flakes).","If persistent, verify the target URL loads in a browser and the WPT location/browser is healthy."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"function lhrHasRuntimeError(lhr) {\n  return Boolean(lhr && lhr.runtimeError && (lhr.runtimeError.code || lhr.runtimeError.message));\n}\nfunction lhrHasRequiredMetrics(lhr) {\n  const m = common.getMetrics(lhr);\n  return Boolean(m?.firstContentfulPaint && m?.interactive && m?.maxPotentialFID && m?.speedIndex);\n}","typeGuard":null,"tryCatchPattern":"for (let attempt = 0; attempt < maxAttempts; attempt++) {\n  const {result: lhr} = await runLighthouse(url);\n  if (!lhrHasRuntimeError(lhr) && lhrHasRequiredMetrics(lhr)) { /* success */ break; }\n  if (attempt === maxAttempts - 1) throw new Error(`runtime error: ${lhr.runtimeError}`);\n}","preventionTips":["Retry runs with runtime errors — most are transient (navigation timeout, protocol flake).","Verify the target URL is healthy before collecting metrics.","Check lhr.runtimeError.code for specific failure categories (e.g. INSECURE_DOCUMENT_REQUEST)."],"tags":["lighthouse","runtime-error","wpt","lantern","retriable"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}