fix(insights): block on cache miss for any dashboard-opened insight - #76386
fix(insights): block on cache miss for any dashboard-opened insight#76386posthog[bot] wants to merge 1 commit into
Conversation
Widen the `async_except_on_cache_miss` escalation added in #75858 from "overrides are non-empty" to "opened from a dashboard", since a saved insight's own cache key can be cold too and that path had no other recovery. Generated-By: PostHog Code Task-Id: a8e2a4e0-48bd-48cf-8ebc-3956899422dd
|
Merging to
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 |
🤖 CI report
|
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.25 MiB · 22 files | no change | ███░░░░░░░ 27.7% of 4.51 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
8.13 MiB · 3,035 files | 🔺 +21 B (+0.0%) | ████████░░ 83.8% 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 |
|---|---|
| 285.6 KiB | ../node_modules/.pnpm/posthog-js@1.409.5/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 |
| 235.5 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 231.5 KiB | ../node_modules/.pnpm/posthog-js@1.409.5/node_modules/posthog-js/dist/module.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.3 KiB | src/lib/api.ts |
| 94.7 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 |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/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.19 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.19 MiB · 17 files | no change | ████░░░░░░ 38.3% of 5.72 MiB |
| Deferred (lazy) | 2.08 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 |
|---|---|
| 718.3 KiB | dist/toolbar/toolbar-app-FT4UJ3IP.css |
| 551.4 KiB | dist/toolbar/chunk-chunk-AGSGCCBT.js |
| 484.6 KiB | dist/toolbar/chunk-chunk-T44C2V5C.js |
| 133.6 KiB | dist/toolbar/chunk-chunk-KBLX73CM.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-T5KY5WYR.js |
| 71.0 KiB | dist/toolbar/toolbar-app-FKUW2FOM.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-27JL52RE.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-3JVI3ZTF.js |
| 20.9 KiB | dist/toolbar/chunk-chunk-HJ3ZJMTU.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 — 🔺 +1.5 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1381.30 MiB · 🔺 +1.5 KiB (+0.0%)
Problem
insight refresh hint shown) kept firing at the same 350–800/day, up to 96 distinct users, 100% dashboard-scoped rate through the day after it shipped.urls.insightViewbuilds the dashboard-tile → insight link by filtering override params withBoolean(value)(products.tsx:1287), andBoolean({})istrue— so almost every dashboard tile click sendsfilters_override={},variables_override={},tile_filters_override={}in the URL, even when nothing is actually overridden.insightOverridesPresentcorrectly treats those empty objects as "no override", which is right for editing/cache-key purposes. ButinsightLogic.loadInsightused that same flag to decide whether to escalate the refresh mode — so a dashboard-opened insight with no real overrides stayed on plainasync. If the insight's own saved-query cache happened to be cold (e.g. it isn't warmed by any dashboard's scheduled refresh yet),asyncreturnsresult: nulland nothing polls or reloads it. TheafterMountforce-refresh ininsightDataLogiccan't help either, since it only runs whencachedInsightis passed through, andInsightAsSceneonly passes it whenhasOverridesis true.Changes
insightLogic.loadInsightnow escalates toasync_except_on_cache_misswhenever the insight was opened with a dashboard id (props.dashboardId != null), not only when overrides are non-empty. Warm and stale keys behave exactly as before; a genuine miss now computes synchronously instead of dead-ending.How did you test this code?
insightLogic.test.ts— added a regression case pinning the refresh param for a dashboard-opened insight with empty overrides (previouslyasync, nowasync_except_on_cache_miss), and a case confirming empty overrides outside dashboard context still useasync. 53/53 tests pass.oxlint/oxfmtviapnpm --filter=@posthog/frontend fix— clean.pnpm --filter=@posthog/frontend typescript:check— no errors on touched files (pre-existing failures elsewhere in the repo, unrelated).Automatic notifications
Docs update
No user-facing docs affected.
🤖 Agent context
Autonomy: Fully autonomous
insightLogic.tsx/insightDataLogic.tsxfirst — found none in flight.posthog/utils.py,posthog/api/services/query.py) that an empty override dict is a cache-key no-op, then found the actual gap is on the frontend refresh-mode decision, not the cache key itself — a dashboard-opened insight has no escalation path at all oncehasOverridesis false, regardless of whether its own cache happens to be cold.insightOverridesPresentitself, but that flag is also used foreditingDisabledReasonand the overrides banner, where empty-object overrides correctly mean "editable, no banner". Scoped the fix to the refresh-mode decision inloadInsightinstead.InsightErrorState/ unattributablequery_kindbucket) untouched — it's a genuine server-side query failure, a different code path, and not what this fix addresses.Created with PostHog Desktop from this inbox report.