Skip to content

fix(storybook): fail play errors fast and fix AccountsTab boot race - #72862

Merged
pauldambra merged 12 commits into
masterfrom
posthog-code/storybook-play-race-fix
Jul 23, 2026
Merged

fix(storybook): fail play errors fast and fix AccountsTab boot race#72862
pauldambra merged 12 commits into
masterfrom
posthog-code/storybook-play-race-fix

Conversation

@pauldambra

Copy link
Copy Markdown
Member

Problem

The AccountsTab expanded-row stories are the most persistent flake in the visual regression suite — five fix attempts since early July (#68802, #69984, #70144, #70243, #71020) and still firing: on 2026-07-22 alone it failed a master run (29904424573), both attempts of a PR run (29903063122), and an unrelated feature branch. Each incident burns 3 attempts × 60s per story (typically 3 stories ≈ 9 minutes of shard time) and fails the shard with an opaque Exceeded timeout of 60000 ms.

Reproduced locally by running the CI storybook build artifact under 4× CDP CPU throttle, with request/console/Storybook-channel tracing and a pre-timeout CDP screenshot + CPU profile. The full causal chain:

  1. The play function races app boot. Storybook starts play() as soon as React commits the app shell, but the accounts table only renders once the scene's data loads — several seconds later on a loaded CI runner. testing-library's default 1s findBy* timeout loses that race: findByTitle('Show more') throws before the table exists, so the row is never expanded. (Captured screenshot at timeout: healthy page, fully rendered table, row collapsed; CPU profile 98% idle — no wedge, just a wait that can never succeed.)
  2. The real error gets buried. The generated test calls postVisit even when play failed (context.hasFailure, intended for failure handling). Our postVisit ignored the flag and ran the full snapshot flow — whose waitForSelector('[data-attr="account-expansion"]', 60000) waited the entire jest budget for an expansion that never happened. Jest then reports a generic timeout instead of the TestingLibraryElementError.
  3. Retries are no-ops for play stories. On retry, the preview answers setCurrentStory with storyUnchanged — loaders and play do not re-run, so attempts 2 and 3 re-snapshot the same broken page and fail identically. That's why incidents always cost the full 3 × 60s.

Changes

  • preview.tsx: set a global testing-library asyncUtilTimeout of 15s, so every story's findBy*/waitFor tolerates slow scene boots by default (root cause fix, benefits all play stories).
  • test-runner.ts postVisit: honor context.hasFailure and skip the snapshot flow, so a failed play surfaces its real error immediately instead of hanging into the jest timeout.
  • test-runner.ts preVisit: on jest retries, force a story remount (re-running loaders and play) so retries genuinely retry, and surface the replayed play function's error if it throws again.
  • AccountsTab.stories.tsx: explicit 30s find budgets in the play functions (belt-and-braces for this known-hot file), waitForSelectorTimeout 60s → 15s so genuine failures fail fast, and comments updated to describe the real failure mode.

How did you test this code?

Local reproduction harness: served the exact storybook-build artifact from the failing CI run and ran the AccountsTab file with the repo's test-runner under CDP CPU throttling (simulating loaded CI runners; failure reproduced 2/2 runs at 4× before the fix, wedging the same stories as CI):

  • Node-side fixes alone (old bundle, still 1s find budget): failures fell from 556s to 97s per file, every failure reported the real Unable to find an element with the title: Show more error, and all 8 retries genuinely remounted and re-ran play (verified via Storybook channel event tracing).
  • With the 15s testing-library budget (bundle's default patched to simulate the preview.tsx change, since a full local storybook rebuild wasn't feasible in the sandbox): 7/7 stories passed on 3 consecutive runs at 4× throttle and 1 run at 6× throttle — conditions that previously wedged every run.
  • oxlint/oxfmt clean on the three files; pnpm --filter=@posthog/frontend typescript:check reports no errors in the changed files (pre-existing unrelated errors exist in this sandbox's environment).
  • What the agent couldn't do: run hogli ci:preflight (no flox python in the sandbox) or rebuild the storybook bundle locally. This PR's own CI run — including the flake-verification job, which re-runs the changed stories 5× — is the authoritative end-to-end check of the preview.tsx change.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

No user-facing docs affected (CI test infrastructure only).

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Investigation started from repeated VR failures on #72766; log forensics across master/PR runs showed the failures pre-date that PR and pinpointed the wedge to consecutive stories in one file. The user then asked for a root-cause fix of the underlying fetch/render race.
  • Diagnosis used a local reproduction harness (CI build artifact + CPU throttling + CDP screenshot/profiler + Storybook channel tracing) rather than source-reading alone; the "expansion collapses on re-render" theory from the file's comments turned out wrong — the expansion was never opened because play lost the boot race, and two test-runner defects (postVisit on failure, storyUnchanged retries) amplified a 1s race into 3×60s opaque hangs.
  • Considered fixing only the stories (per-play timeouts); chose to also fix the two test-runner defects because they amplify any play failure repo-wide. The forceRemount-on-retry uses Storybook's public forceRemount channel event with a 30s in-page settle guard.
  • Related open PRs #72766 and #72768 touch the same file/workflow but different hunks — no conflicts expected in either merge order.

Created with PostHog Code

The AccountsTab expanded-row stories kept timing out in visual regression
CI (3 attempts x 60s per story) despite five prior fix attempts. Reproduced
locally under CPU throttle and traced the full chain:

1. play() starts as soon as React commits the app shell, but the accounts
   table renders only after the scene's data loads — several seconds on a
   loaded runner. testing-library's default 1s findBy* timeout loses that
   race, so `findByTitle('Show more')` threw before the table existed.
2. The generated test still runs postVisit after a play failure (with
   context.hasFailure set, meant for failure handling). Our postVisit
   ignored the flag and ran the full snapshot flow, whose 60s
   waitForSelector outlasted the jest budget — burying the real error
   under "Exceeded timeout of 60000 ms".
3. On jest retries the preview answers setCurrentStory with
   `storyUnchanged`, which does not re-run loaders or play — so retries
   re-tested the same broken page and could never pass.

Fixes: a 15s testing-library asyncUtilTimeout default for all stories
(plus explicit budgets in this file), postVisit honoring hasFailure so
play errors surface immediately, forced story remounts on retries so they
genuinely retry, and a 15s waitForSelector budget instead of 60s.

Verified against the CI storybook build under 4x and 6x CPU throttle:
previously wedged every run at 4x; now 7/7 stories pass repeatedly, and
induced failures report the real error in ~97s instead of ~556s.

Generated-By: PostHog Code
Task-Id: 0c854fe6-a5b4-41de-81ba-e60dcc455a5a
@github-actions

Copy link
Copy Markdown
Contributor

Hey @pauldambra! 👋

It looks like your git author email on this PR isn't your @posthog.com address (paul.dambra@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Bundle size — no change

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

Total: 64.68 MiB · no change

No file changed by more than 1000 B.

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.24 MiB · 22 files no change ███░░░░░░░ 27.5% of 4.51 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.25 MiB · 3,014 files no change ████████░░ 84.9% of 9.71 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.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/RootErrorBoundary.tsx
912 B ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js
789 B src/scenes/ChunkLoadErrorBoundary.tsx
762 B src/index.tsx
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
Size File
281.5 KiB ../node_modules/.pnpm/posthog-js@1.407.1/node_modules/posthog-js/dist/rrweb.js
267.7 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
236.0 KiB src/taxonomy/core-filter-definitions-by-group.json
226.1 KiB ../node_modules/.pnpm/posthog-js@1.407.1/node_modules/posthog-js/dist/module.js
167.1 KiB src/queries/validators.js
154.3 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
105.8 KiB src/lib/api.ts
94.0 KiB ../packages/quill/packages/quill/dist/index.js
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js

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.18 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.18 MiB · 17 files no change ████░░░░░░ 38.1% of 5.72 MiB
Deferred (lazy) 2.07 MiB · 33 files no change n/a — loads on demand
Loader dist/toolbar.js 1.1 KiB no change █░░░░░░░░░ 5.8% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
714.7 KiB dist/toolbar/toolbar-app-MKBF64XP.css
545.3 KiB dist/toolbar/chunk-chunk-HYYFIAXK.js
484.2 KiB dist/toolbar/chunk-chunk-QS5AHYGW.js
133.6 KiB dist/toolbar/chunk-chunk-3HAV52CR.js
131.8 KiB dist/toolbar/chunk-chunk-T5KY5WYR.js
71.0 KiB dist/toolbar/toolbar-app-4WXEV7ZF.js
69.0 KiB dist/toolbar/chunk-chunk-27JL52RE.js
35.6 KiB dist/toolbar/chunk-chunk-EL3T2QEA.js
20.9 KiB dist/toolbar/chunk-chunk-HSIJKX5O.js
12.2 KiB dist/toolbar/chunk-chunk-PIK3PADE.js

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

Dist folder size — no change

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

Total: 1359.33 MiB · no change

Playwright — all passed

All tests passed.

View test results →

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🦔 Hogbox preview · ❌ build failed

The preview didn't come up for commit 79e3c31. See the build log for the failing step. It'll retry on the next push.

Previews are optional and never block merging. A failure here is often a hogland or tailnet hiccup rather than anything in your PR, so the check stays green and this comment is the status.

@pauldambra pauldambra added the stamphog Request AI approval (no full review) label Jul 22, 2026
@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 22, 2026 11:44
@pauldambra
pauldambra enabled auto-merge (squash) July 22, 2026 11:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c697780af9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread common/storybook/.storybook/test-runner.ts Outdated
Comment thread common/storybook/.storybook/test-runner.ts Outdated
@stamphog

stamphog Bot commented Jul 22, 2026

Copy link
Copy Markdown

Note

🤖 stamphog reviewed 4fdabd41804e618e6dbe35854e8358a9a752b199 — verdict: ESCALATE

This rewrites shared Storybook CI test-runner logic (global async timeout, retry/remount semantics, and skip-on-failure behavior) that affects every play-based story across the repo — that's CI tooling risk, and the only reviews that scrutinized it (Codex, Graphite) are pinned to an older commit, not the current head; the newer "approval" comments are posted by the PR author's own account, which doesn't count as independent assurance.

  • Author wrote 0% of the modified lines and has 610 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from hex-security-app[bot].
  • No independent (agent or human) review has approved the current head — Codex and Graphite's reviews, though their P1/P2/silent-failure concerns do appear addressed in the current diff, are marked against an older commit (c697780), not the latest commit.
  • Author (pauldambra) is not on either owning team (@PostHog/team-growth, @PostHog/team-web-analytics) and familiarity is only MODERATE (0% of touched lines previously authored by them), so ownership doesn't supply assurance either.
  • The 'QA Swarm' round-2 approval and the visual-baseline approval are both posted under the PR author's own account, so per policy they read as the author's claim, not independent sign-off, even though styled as automated multi-perspective review.
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 162L, 6F substantive — within ceiling
tier T1-agent / T1d-complex (162L, 6F, cross-cutting, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 53ea910 · reviewed head 4fdabd4

Updated in place — this replaces 1 earlier stamphog review(s) on this PR.

@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Jul 22, 2026

@pauldambra pauldambra left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated comment by QA Swarm — not written by a human

QA Swarm review complete. See inline comment.

Comment thread common/storybook/.storybook/test-runner.ts Outdated

pauldambra commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

Note

🤖 Automated comment by QA Swarm — not written by a human

Multi-perspective review: router (cheap-first pass) + delegated reviewers (qa-team, paul-reviewer, xp-reviewer, security-audit as warranted)

Verdict: ✅ APPROVE (round 2 @ 1f6adbc)

Round 2 reviewed the two commits that landed in response to round 1 (Codex P1/P2 fixes + constant extraction): zero findings. The router verified against Storybook's bundled source that unhandledErrorsWhilePlaying always carries a non-empty serialized-error array (the Array.isArray handling is exactly right), that the REMOUNT_FAILURE_EVENTS extraction preserves semantics at both use sites, and that the removed hasFailure cast is covered by the SDK's own TestContext type. TypeScript check: zero errors reference the changed file.

Key findings

None this round.

Convergence

None — single-reviewer round (no delegation).

Reviewer summaries

Reviewer Assessment
🧭 router Danger LOW, confidence HIGH; verified payload shapes, promise idempotence, and type declarations against installed packages; delegated nothing. One informational pre-existing note: the 30s remount budget is fixed and not scaled by timeoutMultiplier for multi-viewport stories (predates this PR's commits).
Previous rounds (1)

round 1 @ c697780 — ✅ APPROVE: one NIT (redundant hasFailure cast), fixed in e33cbb2 alongside two Codex HIGH findings (unhandled play errors + remount timeout swallowed).


Automated by QA Swarm — not a human review

…etry failures

The forced-remount wait in test-runner.ts's preVisit only listened for storyRendered/storyErrored/storyThrewException/playFunctionThrewException. Storybook can emit unhandledErrorsWhilePlaying and still go on to emit storyRendered for the same run, so a real play error was silently treated as a pass. A remount that hit the 30s timeout fell into the same trap — it resolved but wasn't in the failure list, so a still-running remount could race the snapshot flow.

Also drops a redundant type cast on context.hasFailure — @storybook/test-runner's exported TestContext already declares that field.

Generated-By: PostHog Code
Task-Id: 0c854fe6-a5b4-41de-81ba-e60dcc455a5a
@github-actions
github-actions Bot requested a deployment to preview-pr-72862 July 22, 2026 12:25 In progress
Comment thread common/storybook/.storybook/test-runner.ts
Simplify pass: the remount failure events were listed twice (in-page done
listener and the outer retry-failure check) with nothing tying them
together, so an edit to one could silently drift from the other. One
module-level constant now feeds both, passed into page.evaluate as an
argument since the callback crosses the Node-browser boundary.

Generated-By: PostHog Code
Task-Id: 0c854fe6-a5b4-41de-81ba-e60dcc455a5a
@github-actions
github-actions Bot requested a deployment to preview-pr-72862 July 22, 2026 12:37 In progress
page.evaluate() can reject if the page navigates or its execution context is destroyed mid-remount. The previous .catch(() => undefined) swallowed that into `undefined`, which then read as falsy in the failure check below — silently letting the retry proceed as if the remount had finished cleanly.

Generated-By: PostHog Code
Task-Id: 0c854fe6-a5b4-41de-81ba-e60dcc455a5a
@github-actions
github-actions Bot requested a deployment to preview-pr-72862 July 22, 2026 12:43 In progress
The 30s remount-wait timer was never cancelled, so after the remount
settled via a channel event it still fired ~30s later against the
already-resolved promise — harmless but a leaked timer on every retried
story. finish() now clears it first.

Generated-By: PostHog Code
Task-Id: 0c854fe6-a5b4-41de-81ba-e60dcc455a5a
@pauldambra pauldambra added the stamphog Request AI approval (no full review) label Jul 22, 2026 — with PostHog
stamphog[bot]
stamphog Bot previously approved these changes Jul 22, 2026

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contained fix to Storybook test-runner flakiness (timeout tuning, retry-remount handling, failure short-circuiting) — test infrastructure, not production/deploy code. The diff confirms both Codex P1/P2 concerns (accepting a retry before the real outcome, timeouts passing silently) and the evaluation-error-swallowing issue were actually fixed in code, not just marked resolved.

  • Author wrote 0% of the modified lines and has 10 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 125L, 3F substantive — within ceiling
tier T1-agent / T1c-medium (125L, 3F, two-areas, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 3817e82 · reviewed head aa45c3a

The metalyticsLogic view beacon (POST /api/projects/:id/metalytics/) had no
default MSW mock, so insight-rendering stories hit an unhandled 405 during play.
With the retry now failing on unhandledErrorsWhilePlaying, that surfaced as a
hard failure in stories like Paths and FunnelStepsBarChart. Stub it like the
neighbouring insights/viewed beacon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@stamphog
stamphog Bot dismissed their stale review July 22, 2026 14:54

New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.

stamphog[bot]
stamphog Bot previously approved these changes Jul 22, 2026

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pure test/CI-infrastructure fix (storybook preview config, test-runner retry logic, mock handler, and one stories file) with no production code touched; Codex's two flagged issues (retry not waiting for the real failure event, timeout not counted as failure) and Graphite's silent-evaluation-failure concern are all verifiably fixed in the current diff, giving genuine independent-reviewer assurance beyond the author's own claims.

  • Author wrote 0% of the modified lines and has 18 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from hex-security-app[bot].
  • The 'QA Swarm' discussion comment and inline reply were posted by the PR author's own account, not an independent reviewer — treated as author claim, not assurance, per policy; genuine assurance instead comes from the Codex/Graphite bot findings, which the diff shows were substantively addressed.
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 128L, 4F substantive — within ceiling
tier T1-agent / T1d-complex (128L, 4F, cross-cutting, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 09f143d · reviewed head 58b00f6

RepoPickerOpen failed all three attempts on a loaded VR shard: its waits used a local 8s budget (effectively ~7.5s after the 500ms delayed-mount effect), which loses the same full-App boot race this branch fixed for the AccountsTab stories. Now that retries genuinely re-run play, an under-budgeted wait fails hard instead of silently passing off a late-loaded page. Raise the budget to 30s, matching the AccountsTab precedent.

Generated-By: PostHog Code
Task-Id: 0c854fe6-a5b4-41de-81ba-e60dcc455a5a
@stamphog
stamphog Bot dismissed their stale review July 22, 2026 19:19

New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.

stamphog[bot]
stamphog Bot previously approved these changes Jul 22, 2026

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI test-runner tooling change, but Codex and Graphite each raised concrete correctness concerns about the new retry/remount logic (race on unhandledErrorsWhilePlaying, timeout not treated as failure, silent swallow of evaluate() errors) and the current diff visibly implements exactly those fixes (REMOUNT_FAILURE_EVENTS handling, 30s timeout treated as failure, evaluate().catch() mapped to a failure event) — independent assurance is satisfied and no unresolved concerns remain.

  • Author wrote 0% of the modified lines and has 18 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 136L, 5F substantive — within ceiling
tier T1-agent / T1d-complex (136L, 5F, cross-cutting, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 0c10618 · reviewed head 6b4add4

…meout phase

RepoPickerOpen's play waited for `[data-attr="select-github-repository"] input`, but LemonInput spreads data-attr onto the <input> element itself, so the descendant selector never matched — the play function has never succeeded. The masked-retry behavior this branch removes used to re-snapshot the closed picker in update mode and pass anyway; with retries now honest, the story failed every attempt on every runner. Match the input directly.

Also make the remount-wait timeout diagnosable: it now records the last storyRenderPhaseChanged phase and reports it (e.g. "last render phase: playing") instead of "unknown error", so a remount that times out points at the story's loading/play rather than at the machinery.

Generated-By: PostHog Code
Task-Id: 0c854fe6-a5b4-41de-81ba-e60dcc455a5a
@stamphog
stamphog Bot dismissed their stale review July 22, 2026 19:53

New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.

stamphog[bot]
stamphog Bot previously approved these changes Jul 22, 2026

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test-infrastructure-only change (Storybook test-runner and stories); the diff shows the two Codex P1/P2 correctness issues (accepting a retry on unhandledErrorsWhilePlaying, and not rejecting a timed-out remount) and Graphite's silent-catch concern are all explicitly fixed in the current code (unhandledErrorsWhilePlaying and 'timeout'/'evaluationFailed' are all included in the failure-event check), giving independent agent-reviewer assurance over this CI-tooling change.

  • Author wrote 0% of the modified lines and has 18 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 158L, 5F substantive — within ceiling
tier T1-agent / T1d-complex (158L, 5F, cross-cutting, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 84a0726 · reviewed head 06914e7

@posthog

posthog Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

👋 Visual changes detected for this PR.

Review and approve in PostHog Visual Review

If these changes are unexpected, they may be caused by a flaky test or a broken snapshot on master. Don't approve — rerun the job or wait for a fix.

2 updated
Run: 98a3edaa-542c-464d-a499-9b8af207cf3d

Co-authored-by: pauldambra <984817+pauldambra@users.noreply.github.com>
@stamphog
stamphog Bot dismissed their stale review July 22, 2026 20:32

New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.

@stamphog stamphog Bot removed the stamphog Request AI approval (no full review) label Jul 22, 2026
# Conflicts:
#	products/customer_analytics/frontend/components/Accounts/AccountsTab.stories.tsx
# Conflicts:
#	products/customer_analytics/frontend/components/Accounts/AccountsTab.stories.tsx
@pauldambra pauldambra added the stamphog Request AI approval (no full review) label Jul 23, 2026

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storybook test-runner/harness fix for a well-documented flaky-test race; the genuine bot reviewers (Codex, Graphite) raised real concerns about the new retry logic and those are verifiably fixed in the current diff (unhandled-error listening, timeout rejection, evaluation-error handling all present). The author's own "QA Swarm" self-review comment is not counted as independent assurance, but the real Codex/Graphite reviews satisfy that requirement for this CI-tooling change.

  • Author wrote 0% of the modified lines and has 605 merged PRs in these paths (familiarity MODERATE).
  • 👍 on the PR from hex-security-app[bot].
  • Change modifies CI test-runner retry/failure semantics (test infra, not production code) — independent assurance comes from Codex/Graphite bot reviews whose concerns are verified fixed in the diff, not from the author's self-styled 'QA Swarm' comment.
  • Visual-review bot flagged snapshot changes; the two updated hashes correspond to an intentional selector fix described in the PR (input[data-attr] vs descendant selector) so this reads as expected, not a red flag.
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 132L, 5F substantive — within ceiling
tier T1-agent / T1c-medium (132L, 5F, two-areas, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 9922cca · reviewed head 79e3c31

@pauldambra
pauldambra merged commit ea486f0 into master Jul 23, 2026
296 of 298 checks passed
@pauldambra
pauldambra deleted the posthog-code/storybook-play-race-fix branch July 23, 2026 17:34
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-23 18:00 UTC Run
prod-us ✅ Deployed 2026-07-23 18:28 UTC Run
prod-eu ✅ Deployed 2026-07-23 18:37 UTC Run

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

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant