Skip to content

fix(replay): give the recording placeholder buttons visible feedback - #114821

Draft
posthog[bot] wants to merge 3 commits into
masterfrom
posthog-self-driving/fixreplay-give-feedback-from-reload-on-f2a7ce
Draft

posthog[bot] wants to merge 3 commits into
masterfrom
posthog-self-driving/fixreplay-give-feedback-from-reload-on-f2a7ce

Conversation

@posthog

@posthog posthog Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Problem

  • Viewers who open a recording that cannot play click Reload, see nothing change, and leave. About half of all clicks on these two buttons are dead clicks.
  • Both placeholder screens in PurePlayer.tsx wire Reload to loadSnapshots. That action does nothing while a background source poll is in flight. In other cases it lists the same sources again, and the same screen comes back. The button has no loading state and no result.
  • On the terminal "This recording can't be played" screen, a reload can never help. The first full snapshot never reached PostHog.

Origin

  • Replay Vision
  • First signal: 2026-09-22
  • Inbox report: open
  • Likely cause: 1b02a4a
  • Task started by: auto-start, after the report was rated P3 and ready to fix

Changes

Screen Before After
Can't be played (terminal) Reload button that does nothing No button. The copy says that reloading won't bring the data back.
Still working on it Reload button, no feedback Check for new data, with a loading state, then "It's not ready to play yet. Try again in a minute."
  • New checkForNewSnapshots action and snapshotCheckState reducer (idle → checking → checked) on sessionRecordingDataCoordinatorLogic. Only a viewer click moves the state out of idle, so a background poll cannot show the result line.
  • The check calls loadSnapshotSources directly, not loadSnapshots. The new loader call cancels a poll that waits at its breakpoint, so the click starts a listing at once. If new data makes the recording playable, the placeholder goes away and the player loads.
  • snapshotDataLogic.tsx has no changes, so this PR does not conflict with #111793. The terminal copy edit touches the same paragraph as #108861. Whichever PR merges second needs a one-line rebase.
  • The still-ingesting button keeps data-attr="player-error-retry-load-still-working", so dead-click tracking stays comparable before and after.
Before After
Still working, after a click before checking checked
Can't be played before after

How did you test this code?

  • Jest: sessionRecordingDataCoordinatorLogic.test.ts and the snapshotDataLogic suites pass locally. oxlint and oxfmt are clean on the changed files.
  • Test rationale: the new test starts a background poll with a 60 s breakpoint under fake timers, clicks the check, and advances 1 s. It expects checked. When the check is routed through loadSnapshots, the test fails with checking. That is the dead click from the report. The closest existing tests (missing full snapshot detection) cover only which screen shows, not the button.
  • Visual: both screens rendered in a scratch Storybook story (not committed), with incremental-only snapshot mocks and a mocked date inside and outside the ingestion grace period. The screenshots above come from that story, before and after the change.
  • pnpm typescript:check fails in this sandbox because @posthog/quill is not built. No error is in the changed files.
  • Not checked: a real recording in a running stack.

Release status

  • No feature flag controls this change

Docs update

None. No doc under docs/ covers these placeholder screens.

🤖 Agent context

Autonomy: Fully autonomous

Agent: Claude Code, claude-opus-5-5

  • Started from a PostHog inbox report about dead clicks on these buttons.
  • Reused the UI approach from the closed draft #105538, without its change to the ingestion grace anchor, which is a separate problem.
  • No-duplicate search: #108861 changes only copy, and #111793 changes retry in snapshotDataLogic. Neither one adds feedback to these buttons.
  • Skills: writing-simplified-technical-english.

Created with PostHog Desktop from this inbox report.

🤖 Generated with Claude Code

Remove Reload from the terminal no-full-snapshot screen, because a reload cannot bring that data back. On the still-ingesting screen, the button is now "Check for new data". It shows a loading state, starts a source listing even while a background poll is in flight, and then tells the viewer that the recording is not ready yet.

Generated-By: PostHog Desktop
Task-Id: a7a258da-cc35-45c3-be8b-8e3070fed5a8
@posthog posthog Bot added the self-driving label Oct 9, 2026
@trunk-io

trunk-io Bot commented Oct 9, 2026

Copy link
Copy Markdown

Merging to master in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@posthog posthog Bot assigned ksvat Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🤖 CI report

✅ Trunk lane — non-backend lane

This PR is assigned to the non-backend lane. It does not run backend Python tests and may merge in parallel with PRs in other lanes.

⚠️ Complexity (TypeScript) — 2 functions above the limit (max 27)

Cyclomatic complexity above the limit in changed typescript files (10 for production files, 15 for test files). Warn only: worth simplifying when you next touch these functions.

Function Location Complexity Limit
PurePlayer frontend/src/scenes/session-recordings/player/PurePlayer.tsx:57 27 10
processSnapshotsAsync frontend/src/scenes/session-recordings/player/sessionRecordingDataCoordinatorLogic.ts:788 14 10
✅ Duplication (Python) — clean

New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

✅ Duplication (TypeScript) — clean

New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.

🚨 Comment density — 8% of added code lines are comments (6 of 72)

This section warns when comments are more than 3% of the code lines a PR adds, and alerts above 6%. Before agent-assisted PRs, the typical share was about 2%. Only full-line comments count. Docstrings, generated files, snapshots, migrations, and workflow files are left out.

Comments that restate the code, record how the change came about, or narrate the next line add noise for the next reader. Keep the comments that explain a reason the code cannot show, and remove the rest. See .agents/skills/writing-code-comments/SKILL.md for the house rules.

Files with the most added comment lines:

File Comment lines Added lines
frontend/src/scenes/session-recordings/player/sessionRecordingDataCoordinatorLogic.ts 6 46

This check does not block merging. It updates on every push and clears when the share drops.

⚠️ Bundle size — 🔺 +1.2 KiB (+0.0%)

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 75.52 MiB · 🔺 +1.2 KiB (+0.0%)

File Size Δ vs base
render-query/src/render-query/render-query.js 24.16 MiB 🔺 +1.1 KiB (+0.0%)

Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report

✅ Eager graph — within budget

How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.67 MiB · 23 files no change █████████░ 90.6% of 1.84 MiB
logged-out boot: index + App + bootApp (preloaded by every page, including /login)
src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
3.82 MiB · 675 files 🔺 +710 B (+0.0%) █████████░ 94.8% of 4.03 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
7.78 MiB · 2,463 files 🔺 +710 B (+0.0%) █████████░ 93.2% of 8.34 MiB
dashboard scene
src/scenes/dashboard/Dashboard.tsx
9.92 MiB · 3,517 files 🔺 +710 B (+0.0%) █████████░ 90.8% of 10.92 MiB
today home path
src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
7.79 MiB · 2,473 files 🔺 +710 B (+0.0%) █████████░ 90.8% of 8.58 MiB
events scene
src/scenes/activity/explore/EventsScene.tsx
9.53 MiB · 3,361 files 🔺 +710 B (+0.0%) █████████░ 90.6% of 10.51 MiB
replay detail scene
src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
12.33 MiB · 4,192 files 🔺 +1.1 KiB (+0.0%) ████████░░ 78.4% of 15.72 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/activity/explore/EventsScene.tsx

Largest files eagerly shipped from src/index.tsx
Size File
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
24.6 KiB ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js
6.3 KiB ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
4.5 KiB ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js
3.9 KiB ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js
1.4 KiB ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1.3 KiB src/index.tsx
1.3 KiB src/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
839 B src/scenes/ChunkLoadErrorBoundary.tsx
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
Size File
317.7 KiB ../node_modules/.pnpm/posthog-js@1.438.4_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
220.8 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
99.6 KiB src/lib/api.ts
93.6 KiB src/products.tsx
69.0 KiB src/lib/lemon-ui/icons/icons.tsx
40.7 KiB src/lib/utils/eventUsageLogic.ts
38.7 KiB ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js
33.9 KiB ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js
29.0 KiB ../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
317.7 KiB ../node_modules/.pnpm/posthog-js@1.438.4_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.8 KiB src/taxonomy/core-filter-definitions-by-group.json
220.8 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.1 KiB ../packages/quill/packages/quill/dist/index.js
99.6 KiB src/lib/api.ts
93.6 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
Size File
317.7 KiB ../node_modules/.pnpm/posthog-js@1.438.4_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.8 KiB src/taxonomy/core-filter-definitions-by-group.json
220.8 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.9 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.1 KiB ../packages/quill/packages/quill/dist/index.js
99.6 KiB src/lib/api.ts
93.6 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
Size File
317.7 KiB ../node_modules/.pnpm/posthog-js@1.438.4_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.8 KiB src/taxonomy/core-filter-definitions-by-group.json
220.8 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.1 KiB ../packages/quill/packages/quill/dist/index.js
99.6 KiB src/lib/api.ts
93.6 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
Size File
317.7 KiB ../node_modules/.pnpm/posthog-js@1.438.4_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
280.8 KiB src/taxonomy/core-filter-definitions-by-group.json
220.8 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.9 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.1 KiB ../packages/quill/packages/quill/dist/index.js
99.6 KiB src/lib/api.ts
93.6 KiB src/products.tsx
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
Size File
317.7 KiB ../node_modules/.pnpm/posthog-js@1.438.4_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs
316.0 KiB ../node_modules/.pnpm/posthog-js@1.438.4_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js
280.8 KiB src/taxonomy/core-filter-definitions-by-group.json
220.8 KiB ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js
181.9 KiB src/queries/validators.js
153.7 KiB ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js
126.8 KiB ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js
112.1 KiB ../packages/quill/packages/quill/dist/index.js
99.6 KiB src/lib/api.ts
93.6 KiB src/products.tsx

Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479

✅ Toolbar bundle — eager 2.24 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.24 MiB · 19 files 🔺 +710 B (+0.0%) ████░░░░░░ 39.2% of 5.72 MiB
Deferred (lazy) 2.19 MiB · 44 files no change n/a — loads on demand
Loader dist/toolbar.js 1.2 KiB no change █░░░░░░░░░ 6.0% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
865.2 KiB dist/toolbar/toolbar-app-46YQ5DFZ.css
671.0 KiB dist/toolbar/chunk-chunk-2OSLOBKH.js
259.5 KiB dist/toolbar/chunk-chunk-DS74BCMD.js
138.9 KiB dist/toolbar/chunk-chunk-TH2HJYY3.js
131.8 KiB dist/toolbar/chunk-chunk-FDH2IBXT.js
75.2 KiB dist/toolbar/toolbar-app-ZWNPQBAA.js
69.0 KiB dist/toolbar/chunk-chunk-TSAL54PB.js
35.6 KiB dist/toolbar/chunk-chunk-VD4HB63I.js
21.7 KiB dist/toolbar/chunk-chunk-XFPYVCN6.js
6.8 KiB dist/toolbar/chunk-chunk-DV7IWQNF.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

✅ Dist folder size — 🔺 +44.9 KiB (+0.0%)

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1006.78 MiB · 🔺 +44.9 KiB (+0.0%)

posthog Bot added 2 commits October 9, 2026 23:24
Generated-By: PostHog Desktop
Task-Id: a7a258da-cc35-45c3-be8b-8e3070fed5a8
Generated-By: PostHog Desktop
Task-Id: a7a258da-cc35-45c3-be8b-8e3070fed5a8
@trunk-io

trunk-io Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Static Badge   Static Badge   Static Badge

Failed Test Failure Summary Logs
Scenes-App/Project Homepage ProjectHomepage smoke-test The test timed out while waiting for loading indicators or spinners to disappear. Logs ↗︎
Scenes-App/Notebooks/Nodes/Customer Journey AllStepsCompleted smoke-test The test timed out while waiting for an element with the class '.react-flow__node' to become visible. Logs ↗︎
Scenes-Other/Startup program NeedsBillingDetails smoke-test The test timed out while waiting for loading indicators or spinners to disappear. Logs ↗︎
Scenes-App/Experiments ExperimentWithHealthFindings play-test The Storybook test could not find the expected text “Why?” because the scene remained stuck on a loading spinner. Logs ↗︎

... and 3 more

View Full Report ↗︎ ⋅ Docs

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant