GoogleChrome/lighthouse · error · LighthouseError
INVALID_SPEEDLINE
INVALID_SPEEDLINE
Error message
Chrome didn't collect any screenshots during the page load. Please make sure there is content visible on the page, and then try re-running Lighthouse. ({errorCode}) What it means
The screenshot-thumbnails audit runs SpeedLine (a visual progress analysis library) on the trace, then filters to non-interpolated frames. If zero analyzed frames remain after filtering, or if the computed timelineEnd is not a finite number (e.g., SpeedLine failed to produce a valid beginning timestamp), Lighthouse throws a LighthouseError with code INVALID_SPEEDLINE. Like error 15, this is an lhrRuntimeError surfaced in the LHR. The condition checks both analyzedFrames.length === 0 and Number.isFinite(timelineEnd).
Source
Thrown at core/audits/screenshot-thumbnails.js:92
/** @type {Map<SpeedlineFrame, string>} */
const cachedThumbnails = new Map();
const speedline = await Speedline.request(trace, context);
// Make the minimum time range 3s so sites that load super quickly don't get a single screenshot
const minimumTimelineDuration = context.options.minimumTimelineDuration || 3000;
const numberOfThumbnails = context.options.numberOfThumbnails || NUMBER_OF_THUMBNAILS;
const thumbnailWidth = context.options.thumbnailWidth || null;
const thumbnails = [];
const analyzedFrames = speedline.frames.filter(frame => !frame.isProgressInterpolated());
const maxFrameTime =
speedline.complete ||
Math.max(...speedline.frames.map(frame => frame.getTimeStamp() - speedline.beginning));
const timelineEnd = Math.max(maxFrameTime, minimumTimelineDuration);
if (!analyzedFrames.length || !Number.isFinite(timelineEnd)) {
throw new LighthouseError(LighthouseError.errors.INVALID_SPEEDLINE);
}
for (let i = 1; i <= numberOfThumbnails; i++) {
const targetTimestamp = speedline.beginning + timelineEnd * i / numberOfThumbnails;
/** @type {SpeedlineFrame} */
// @ts-expect-error - there will always be at least one frame by this point. TODO: use nonnullable assertion in TS2.9
let frameForTimestamp = null;
if (i === numberOfThumbnails) {
frameForTimestamp = analyzedFrames[analyzedFrames.length - 1];
} else {
analyzedFrames.forEach(frame => {
if (frame.getTimeStamp() <= targetTimestamp) {
frameForTimestamp = frame;
}
});
}
View on GitHub (pinned to 9515cd4e58)
Solutions
- Update Chrome to a version compatible with your Lighthouse version (check Lighthouse's chromeVersion requirement)
- Ensure the page produces visible visual changes during load (not a fully cached instant load)
- In headless environments, enable software rendering: --chrome-flags="--use-gl=swiftshader"
- Retry the run — SpeedLine can fail intermittently on traces that are valid but edge-case
- If using saved traces/artifacts, verify the trace file is not corrupted or truncated
Example fix
# before lighthouse https://example.com --chrome-flags="--headless --no-sandbox" # after (enable rendering for visual progress) lighthouse https://example.com --chrome-flags="--headless --no-sandbox --use-gl=swiftshader"
Defensive patterns
Strategy: fallback
Validate before calling
// Verify the trace has visual frames before running screenshot-thumbnails analysis
// (Applicable when processing saved traces/artifacts)
function verifyTraceHasFrames(traceEvents) {
const screenshotEvents = traceEvents.filter(e => e.name === 'Screenshot');
if (screenshotEvents.length === 0) {
console.warn('Trace has no screenshot events — speedline/screenshot audits will fail');
}
} Try / catch
// When using the programmatic API, check for INVALID_SPEEDLINE in runtimeError
const result = await lighthouse(url, flags, config);
if (result.lhr.runtimeError && result.lhr.runtimeError.code === 'INVALID_SPEEDLINE') {
console.warn('SpeedLine analysis failed — retrying with software rendering');
flags.chromeFlags = '--use-gl=swiftshader';
} Prevention
- Ensure Chrome can render visual frames by adding --use-gl=swiftshader in headless
- Use a Chrome version compatible with your Lighthouse version
- Avoid running on pages with no visual changes (fully cached instant loads)
- Retry on intermittent failures — trace analysis can be sensitive to timing
When it happens
Trigger: SpeedLine processes the trace but all frames are marked as interpolated (isProgressInterpolated returns true for every frame), leaving zero real frames. Alternatively, speedline.complete is falsy and the max frame time calculation produces NaN or Infinity, making timelineEnd non-finite.
Common situations: Traces from pages with very minimal or no visual changes where SpeedLine interpolates all frames; corrupted or incomplete trace files; Chrome version mismatches producing trace events SpeedLine cannot parse; running on pages with near-instant loads that produce no perceptible visual progress; CI/headless environments with rendering issues.
Related errors
AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13).
Data as JSON: /api/errors/316912f1a8dea83d.
Report an issue: GitHub.