Extension content script timeouts and snapshot errors
Dashboard: DOM recorder in Axiom
Service: Chrome Extension
Overview​
The extension captures DOM snapshots of a page for session replay and automation evidence. Snapshot serialization (rrweb takeFullSnapshot()) is synchronous and runs on the page's main thread, so a heavy page blocks everything while it serializes. Almost every snapshot timeout or capturePage failure traces back to this cost.
A snapshot request travels through four layers, each with its own timeout and failure mode, so "the snapshot failed" can mean very different things:
- Slow page serialization — the page is too expensive to snapshot in time (most common root cause).
- Recorder problem — the injected recorder is alive but can't produce a result (overlapping requests, stale lock, or a dead realm after navigation).
- Content-script timeout — the request reached the content script but got no timely answer (usually a symptom of slow serialization or a recorder problem).
- Background gave up — the background service stopped retrying after its own timeout.
Start on the dashboard​
Open the Snapshot performance (recorder) dashboard. If you have the affected session, set the Session ID filter and adjust the time range, otherwise set the time range around the failure:
- Serialization latency p50 / p95 / p99 (ms) and Heavy serializations (> 2s / > 10s) — show whether serialization is taking too long. A rising p95/p99 or a spike of
> 10ssnapshots points to slow page serialization. - Snapshot outcomes (serialized / cacheHit / skipped) and Cache vs Skip — show whether the circuit breaker (
skipped) and cache are engaging as expected. A surge ofskippedmeans pages are repeatedly too heavy to serialize. - Page stats on slow snapshots > 1s — averages of
longTaskTotalMs,nodeCount,topFrameCanvasCount,topFrameImageCountfor slow snapshots. High canvas/image counts are usually the real driver (heavy content inlined synchronously). highlongTaskTotalMsmeans the page itself was contending for the main thread. Node count alone is a weak predictor. - capturePage failures & content-script timeouts — confirms what actually failed and classifies it:
timeout (no retry),failed (retries exhausted), orskipped (max duration). Start here to know which failure mode you are dealing with.
Dig into the raw logs​
When the dashboard isn't enough and you need to dig deeper, query the logs dataset (service legion-extension). Scope every query with the session id from the dashboard.
- Full timeline for one session — order everything the extension logged to see the last successful step before the failure:
['logs']
| where ['service.name'] == "legion-extension"
| where tostring(['attributes.sessionId']) == "RELEVANT_SESSION_ID"
| project _time, body, ['attributes.host'], ['attributes.durationMs'], ['attributes.isTimeout']
| sort by _time asc
- Content-script timeout vs dead recorder —
Persistent snapshot timed out/Timed out after 12000msare timeouts, not crashes, the work may still be running on a frozen thread. After a timeout the content script pings the recorder and logsrecorder ping after timeout:alive→ slow page serialization. The recorder is fine, the page was just too slow. Expect arecorder snapshot metricsline with a largedurationMsto arrive after the timeout.no response→ recorder problem. The recorder realm is dead (page wiped) and needs re-injection.
['logs']
| where ['service.name'] == "legion-extension"
| where tostring(['attributes.sessionId']) == "RELEVANT_SESSION_ID"
| where body contains "ping after timeout" or body contains "snapshot timed out" or body contains "Timed out after"
| project _time, body, ['attributes.host']
| sort by _time asc
- Recorder-level errors —
Snapshot already in progress(overlapping requests during a freeze) or a non-emptystaleLockReclaimedAfterMs(a prior snapshot didn't release its lock cleanly) both indicate a recorder problem, not slow page serialization. - No telemetry at all — if there is no
recorder snapshot metricsline for the host/session, the recorder likely was not injected or the page was non-capturable.
Actions​
- Open a Linear issue and attach the affected
host, the relevant data from telemetry, and which root cause was identified (slow page serialization, recorder problem, etc.). - If the issue started after a recent release, treat it as a likely regression and prioritize rollback/fix decisions.