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/debugging-local-replay@PostHog? Sign in with GitHub to claim this listing.Comprehensive local debugging guide with clear symptom mapping and full pipeline coverage
1---2name: debugging-local-replay3description: >4 Debugs why session recordings aren't appearing in the local dev environment.5 Use when a developer reports that local replay ingestion isn't working,6 recordings aren't showing up despite /s calls, or the replay pipeline7 seems broken after hogli start. Covers the full local pipeline:8 SDK capture, Caddy proxy, capture-replay (Rust), Kafka, ingestion-sessionreplay (Node),9 recording-api (Node), SeaweedFS, and common failure modes like orphaned processes,10 stuck phrocs workers, and trigger misconfiguration.11---1213# Debugging local session replay1415When a developer says "local replay isn't working" or "recordings aren't showing up",16work through these layers in order.17The local replay pipeline has several moving parts and failures are usually silent.1819## Quick symptom guide2021| Symptom | Likely cause |22| ------------------------------------------------------ | ----------------------------------------------------------------------------------------- |23| No `/s` calls in Network tab | SDK not recording — triggers, settings, or recorder script issue (Step 1) |24| `/s` calls return 200 but no recordings in list | Ingestion pipeline broken — capture-replay, Kafka, or ingestion-sessionreplay (Steps 2-3) |25| Recordings listed but playback stuck on "Buffering..." | `recording-api` (port 6741) not running (Step 2) |26| Recorder script MIME type or CORS error in console | Frontend build stale — need `pnpm build` + `pnpm copy-scripts` (Step 1) |2728## The local replay pipeline2930```text31Browser SDK → /s endpoint (Caddy proxy :8000)32 → capture-replay (Rust, :3306)33 → Kafka (session_recording_snapshot_item_events topic)34 → ingestion-sessionreplay (Node, :6740, PLUGIN_SERVER_MODE=recordings-blob-ingestion-v2)35 → SeaweedFS (blob storage, :8333)36 → recording-api (Node, :6741, PLUGIN_SERVER_MODE=recording-api)37 → Frontend38```3940A break at any point in this chain means no recordings in the UI.41The diagnostic approach is to find where the chain breaks.4243## Step 1 — Is the SDK even trying to record?4445Ask the developer to open browser DevTools Network tab and filter for `/s`.4647**If no `/s` calls at all:**48The SDK isn't attempting to send recording data. Investigate client-side causes:4950- **Triggers configured in project settings.** If URL triggers, event triggers, or linked flag triggers51 are set up, recording won't start until a trigger fires. This is the most common cause for52 developers who've been testing trigger features. Check Session replay settings in the local UI53 (Project settings > Session replay). Remove or adjust triggers to allow recording to start.54- **Recording disabled in project settings.** Session replay may be toggled off.55- **Sample rate set too low.** If `$replay_sample_rate` is < 1.0, sessions may be sampled out.56- **SDK not initialized with recording.** Check the local app's PostHog initialization —57 `session_recording` must not be explicitly disabled.58- **Wrong PostHog host.** The local app must point to `http://localhost:8000` (or wherever59 the local Caddy proxy is running).60- **Ad blocker.** Even in local dev, browser extensions can block the recorder script or `/s` endpoint.61- **Recorder script failed to load (MIME type / CORS error).** The browser console may show62 `MIME type ('text/html') is not executable` for `posthog-recorder.js` or a CORS error for63 `lazy-recorder.js`. This means Django is serving an HTML page (usually the login redirect)64 instead of the JS file — the static recorder scripts are stale or missing.65 See [recorder script build failure](./references/common-failures.md#recorder-script-build-failure).6667**If `/s` calls are happening with 200 responses:**68The SDK is recording and capture is receiving data. The break is downstream — proceed to Step 2.6970**If `/s` calls are returning errors (4xx/5xx):**71The capture service may be down or misconfigured. Check `capture-replay` in phrocs.7273## Step 2 — Are the required processes running?7475Check that these phrocs processes are running and healthy.76A "running" process that never produced output after `tsx watch src/index.ts` is effectively dead.7778### Key processes and their ports7980| Process | Port | What it does |81| ------------------------- | ---- | ------------------------------------------------ |82| `capture-replay` | 3306 | Rust service receiving `/s`, writes to Kafka |83| `ingestion-sessionreplay` | 6740 | Node consumer processing recordings from Kafka |84| `recording-api` | 6741 | Node service serving replay data to the frontend |8586Verify with:8788```bash89lsof -nP -i :3306 -i :6740 -i :674190```9192**If ports are not listening:**93The processes haven't started or are stuck. See [common failures](./references/common-failures.md).9495**If ports are listening:**96The pipeline processes are running. Proceed to Step 3.9798### Docker dependencies99100These Docker containers must be running and healthy:101102| Container | Purpose |103| ---------------------- | -------------------------------- |104| `posthog-kafka-1` | Message bus for recording events |105| `posthog-db-1` | Postgres for metadata |106| `posthog-redis7-1` | Redis for state |107| `posthog-clickhouse-1` | ClickHouse for session data |108| `seaweedfs-main` | Blob storage for recording data |109110Check with:111112```bash113docker ps --format "table {{.Names}}\t{{.Status}}" | grep -E "kafka|db|redis7|clickhouse|seaweed"114```115116All should show `(healthy)` except seaweedfs which doesn't have a health check.117If `seaweedfs-main` is missing, the `replay` Docker profile may not be active —118check the `docker-compose` phrocs process output for `--profile replay`.119120## Step 3 — Is data flowing through Kafka?121122If capture-replay is running and receiving `/s` calls, data should land on the123`session_recording_snapshot_item_events` Kafka topic. Check the Kafka UI at124`http://localhost:8080` (if the `debug_tools` intent is enabled) or use kcat:125126```bash127kcat -b localhost:9092 -t session_recording_snapshot_item_events -C -c 5 -e128```129130**If the topic is empty or doesn't exist:**131capture-replay isn't writing to Kafka. Check its phrocs logs for Kafka connection errors.132133**If data is on the topic but recordings don't appear:**134ingestion-sessionreplay isn't consuming. Check if it's stuck, crashed, or if an135orphaned process is holding the consumer group (see common failures).136137## Step 4 — Check SeaweedFS138139Ingestion writes recording blobs to SeaweedFS. Verify it's accessible:140141```bash142curl -s http://localhost:8333/ | head -5143```144145The `SESSION_RECORDING_V2_S3_ENDPOINT` env var must be set correctly.146In `bin/start`, this defaults to `http://seaweedfs:8333` (the Docker hostname).147Host processes resolve this via Docker networking.148149## Common failures reference150151See [common failures](./references/common-failures.md) for detailed diagnosis of:152153- Orphaned Node processes holding Kafka consumer groups154- Processes stuck at `bin/wait-for-docker`155- tsx watch silently swallowing crashes156- Port conflicts between Docker and host processes157- Cargo build lock contention on startup158
Full transparency — inspect the skill content before installing.