A collection of PostHog skills for enhancing AI-assisted workflows. Add this repo as a Claude Code plugin marketplace to get access to all PostHog skills: Then install individual plugins: Or browse available plugins: Copy any skill directory to .claude/skills/ in your project: Any directory under skills/ that contains a .claude-plugin/plugin.json is automatically discovered and added to the market
Add this skill
npx mdskills install PostHog/diagnosing-missing-recordings@PostHog? Sign in with GitHub to claim this listing.Comprehensive diagnostic workflow with structured decision logic and actionable remediation paths
1---2name: diagnosing-missing-recordings3description: >4 Diagnoses why a session recording is missing or was not captured.5 Use when a user asks why a session has no replay, why recordings aren't appearing,6 or wants to troubleshoot session replay capture issues for a specific session ID7 or across their project. Covers SDK diagnostic signals, project settings,8 sampling, triggers, ad blockers, and quota/billing scenarios.9---1011# Diagnosing missing session recordings1213When a user asks "why wasn't this session recorded?" or "why don't I have any recordings?",14follow this workflow to systematically diagnose the cause.1516## Available tools1718| Tool | Purpose |19| --------------------------------------- | ----------------------------------------------------- |20| `posthog:execute-sql` | Query session event properties for diagnostic signals |21| `posthog:session-recording-get` | Check if a recording actually exists for the session |22| `posthog:query-session-recordings-list` | Search for recordings matching criteria |2324## Diagnostic signals2526The PostHog SDK emits diagnostic properties on every event that explain the recording state.27See the [diagnostic signals reference](./references/diagnostic-signals.md) for the full list.2829The key signals are:3031- `$has_recording` — whether PostHog has a stored recording for this session32- `$recording_status` — SDK state: `active`, `buffering`, `disabled`, `sampled`, `paused`33- `$session_recording_start_reason` — why recording started or didn't34- `$sdk_debug_recording_script_not_loaded` — recorder script blocked (ad blocker)35- `$sdk_debug_replay_*_trigger_status` — trigger states (URL, event, linked flag)36- `$replay_sample_rate` — configured sample rate at capture time3738## Workflow3940### Step 1 — Check if the recording exists4142If the user provides a session ID, first check whether a recording actually exists:4344```json45posthog:session-recording-get46{47 "id": "<session_id>"48}49```5051If this returns data, the recording exists — the issue is likely UI/filtering, not capture.52If it returns 404, proceed to diagnose why.5354### Step 2 — Query diagnostic signals from events5556Query the most recent event for the session to get SDK diagnostic properties:5758```sql59posthog:execute-sql60SELECT61 properties.$has_recording AS has_recording,62 properties.$recording_status AS recording_status,63 properties.$session_recording_start_reason AS start_reason,64 properties.$sdk_debug_recording_script_not_loaded AS script_not_loaded,65 properties.$sdk_debug_replay_url_trigger_status AS url_trigger,66 properties.$sdk_debug_replay_event_trigger_status AS event_trigger,67 properties.$sdk_debug_replay_linked_flag_trigger_status AS flag_trigger,68 properties.$replay_sample_rate AS sample_rate,69 properties.$sdk_debug_replay_internal_buffer_length AS buffer_length,70 properties.$sdk_debug_replay_flushed_size AS flushed_size,71 properties.$lib AS sdk_library,72 properties.$lib_version AS sdk_version73FROM events74WHERE $session_id = '<session_id>'75ORDER BY timestamp DESC76LIMIT 177```7879### Step 3 — Diagnose the verdict8081Use the [diagnosis logic reference](./references/diagnosis-logic.md) to interpret the signals.82The verdicts in priority order:83841. **Recording exists** (`$has_recording = true`) — recording is captured, issue is elsewhere852. **Ad blocked (script)** (`$sdk_debug_recording_script_not_loaded = true`) — browser extension blocking the recorder script from loading863. **Disabled** (`$recording_status = 'disabled'`) — replay turned off in settings or SDK config874. **Trigger pending** (trigger statuses are `trigger_pending`, none matched) — recording gated on trigger that never fired885. **Sampled out** (`$session_recording_start_reason = 'sampled_out'`) — excluded by sample rate896. **Buffering empty** (`$recording_status = 'buffering'`, buffer length = 0, nothing flushed) — initialized but no snapshots produced907. **Flush blocked** (buffer length climbs across events while `flushed_size` stays at 0) — snapshots are produced but the `/s/` ingestion endpoint is blocked by an ad blocker or misconfigured reverse proxy. Detecting this requires querying the trend across the session's events — see [example 3 in examples.md](./references/examples.md)918. **Unknown** — signals don't match a known pattern9293### Step 4 — Check project-level settings (if no session ID)9495When the user asks about recordings missing project-wide (no specific session),96query for recent sessions to check the pattern:9798```sql99posthog:execute-sql100SELECT101 $session_id,102 properties.$recording_status AS recording_status,103 properties.$session_recording_start_reason AS start_reason,104 properties.$sdk_debug_recording_script_not_loaded AS script_not_loaded,105 properties.$replay_sample_rate AS sample_rate106FROM events107WHERE event = '$pageview'108 AND timestamp > now() - INTERVAL 1 DAY109GROUP BY110 $session_id,111 recording_status,112 start_reason,113 script_not_loaded,114 sample_rate115ORDER BY max(timestamp) DESC116LIMIT 10117```118119Look for patterns:120121- All `disabled` → replay is turned off in project settings122- All `sampled_out` with low sample rate → sample rate too aggressive123- All `script_not_loaded` → likely a CSP or deployment issue, not just one user's ad blocker124- Mix of statuses → per-session issue, dig into specifics125126### Step 5 — Provide actionable recommendations127128Based on the verdict, recommend specific actions:129130| Verdict | Recommendation |131| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |132| Ad blocked | User's browser extension is blocking rrweb. Suggest trying without ad blocker, or using a proxy/custom domain for the recorder script |133| Disabled | Check project replay settings — recording may be turned off. Link to Settings > Session replay |134| Trigger pending | The configured trigger (URL pattern, event, or feature flag) never matched. Review trigger configuration |135| Sampled out | Increase the sample rate in project settings, or use a trigger to guarantee capture for important sessions |136| Buffering empty | Page closed before first snapshot. Common with very short sessions or single-page navigations. Consider lowering minimum duration |137| Unknown | Direct user to troubleshooting docs: https://posthog.com/docs/session-replay/troubleshooting |138139## Examples140141See [real-world diagnostic examples](./references/examples.md) showing how signal combinations142map to verdicts. Use these to calibrate your interpretation of query results.143144## Tips145146- If `$lib_version` is very old, some diagnostic signals won't be present.147 Note this to the user — upgrading the SDK will provide better diagnostics.148- A session might have events but no recording if the recording was deleted due to retention.149 Check the session's timestamp against the project's retention period.150- If `$has_recording` is true but the user can't find it, check if it's filtered out151 by duration, activity threshold, or playlist filters.152
Full transparency — inspect the skill content before installing.