fix(max): stop showing "no matching events" on empty AI previews#67284
fix(max): stop showing "no matching events" on empty AI previews#67284posthog[bot] wants to merge 1 commit into
Conversation
PostHog AI previews re-run the assistant's generated query live. When that query comes back with no rows (e.g. a funnel whose generated definition diverges from the SQL the assistant actually executed), InsightVizDisplay fell through to the default InsightEmptyState copy: "There are no matching events for this query" plus advice to change filters the user can't edit in the preview. This reads as a dead-end even when the assistant already found the answer, eroding trust in the AI output. Feed a Max-specific empty-state context (heading + detail) into every Max query preview render path so the message reflects reality and points at the assistant's actual output. The copy lives in one shared constant in scenes/max/utils.ts. Generated-By: PostHog Code Task-Id: 6431bd6c-c56b-42f5-95e8-1227a615d4d5
|
Size Change: 0 B Total Size: 69.9 MB ℹ️ View Unchanged
|
🕸️ Eager graphHow much code each root forces the browser to download and decode through static imports — the regression class total bundle size can't see.
✅ Largest files eagerly reachable from
|
| 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 |
| 668 B | src/index.tsx |
Largest files eagerly reachable from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 277.1 KiB | ../node_modules/.pnpm/posthog-js@1.398.2/node_modules/posthog-js/dist/rrweb.js |
| 266.9 KiB | ../node_modules/.pnpm/@posthog+icons@0.37.4_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 224.6 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 213.6 KiB | ../node_modules/.pnpm/posthog-js@1.398.2/node_modules/posthog-js/dist/module.js |
| 160.9 KiB | src/queries/validators.js |
| 154.0 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 |
| 106.1 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.5 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.1_@tiptap+pm@3.20.1/node_modules/@tiptap/core/dist/index.js |
Posted automatically by check-eager-graph · sizes are input-source bytes from the esbuild metafile · part of #32479
|
👋 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. |
|
Heads-up for review: the Visual Review run flags changed snapshots, and those changes are expected — they are this PR working as intended, not a regression. This PR changes the empty-state copy shown when a PostHog AI insight preview renders no rows: from the generic "There are no matching events for this query" to "This preview returned no results" (with detail pointing at the assistant’s actual output). In Storybook, query responses are mocked to return empty results, so the Max stories that render funnel/insight previews (e.g. No committed snapshot PNGs correspond to these stories (their baselines live on the Visual Review platform), so there is nothing to regenerate in the repo. The diffs just need a human to accept the new baseline. Automated checks status: the full sharded jest matrix (the merge gate), semgrep, and typecheck are all green. |
|
This PR hasn't seen activity in a week! Should it be merged, closed, or further worked on? If you want to keep it open, please remove the |
Problem
Users hit a "There are no matching events for this query" empty state on PostHog AI insight previews even when the data is right there. When PostHog AI generates an insight preview, the widget re-runs the assistant's generated query live. If that query is an
InsightVizNode(e.g. a funnel) that comes back with no rows,InsightVizDisplayfalls through to the defaultInsightEmptyState: the generic "There are no matching events for this query" heading plus "Try changing the date range, or pick another action, event or breakdown."That copy is wrong for this context. The user can't edit filters on an inline AI preview, and the assistant often already found the answer, sitting in the executed-query step just above the preview. So the assistant looks like it found nothing when it actually did, which erodes trust in the AI output.
Changes
The empty-state gate in
InsightVizDisplayalready readscontext.emptyStateHeading/context.emptyStateDetail, but the Max render paths weren't passing them, so the generic defaults showed. This adds a sharedPOSTHOG_AI_PREVIEW_EMPTY_STATEconstant (inscenes/max/utils.ts) with accurate copy and wires it into every Max query preview render path:VisualizationWidget(sandbox + langgraph artifact previews) — composed into its existingposthog_aiquery context.Visualization,MultiVisualizationAnswer, andMultiVisualizationModalrenderers inThread.tsx.NotebookArtifactAnswer's visualization block preview.New copy: heading "This preview returned no results", detail "PostHog AI re-runs this query live, so it can come back empty even when the assistant already found the answer. Check the assistant's steps above for the full results."
I deliberately did not add the
limitContext: 'posthog_ai'query-limit flag to the legacy paths (onlyVisualizationWidgethad it) to keep this change scoped to the empty-state copy and avoid altering backend query behavior for those previews.Scope note: this fixes the misleading message the user actually observed. The deeper reconciliation — making the generated preview query identical to the query the assistant executed so the preview isn't empty in the first place — is an agent/backend concern and is out of scope here.
How did you test this code?
This environment had no
node_modulesand no flox, so I could not run the frontend, typecheck, oxfmt, or Storybook, and I have not visually reproduced the state. Verification is by code inspection:InsightVizDisplay.tsxrenders<InsightEmptyState heading={context?.emptyStateHeading} detail={context?.emptyStateDetail} />, andInsightEmptyStateonly falls back to the generic "no matching events" default when those props areundefined— so supplying the context deterministically overrides the copy on both the funnel gate and theDataTableempty state that Max previews flow through.A reviewer should confirm visually: ask PostHog AI for a funnel/insight whose generated preview returns no rows and check the preview now shows the new copy instead of "There are no matching events for this query".
Automatic notifications
🤖 Agent context
Autonomy: Fully autonomous
Authored by Claude Code (Opus 4.8) from an inbox report about the misleading empty state on PostHog AI insight previews.
Investigation traced the string to its single source of truth — the default
headingprop ofInsightEmptyStateinEmptyStates.tsx— then to the only gate that renders it for insight-viz previews (InsightVizDisplay.tsx:280, funnel path) and theDataTablepath, both of which already honorcontext.emptyStateHeading/emptyStateDetail. The fix is to pass that context from the Max render paths, which previously passed none (exceptVisualizationWidget, which passed onlylimitContext).Considered but rejected for this PR: plumbing the assistant's already-computed results into the preview so it isn't empty at all. That needs the preview query to match the executed query and is an agent-side/backend problem, not a widget change. Left the
limitContextflag off the legacy paths so this stays a pure copy fix.Created with PostHog Code from an inbox report.