fix(web-analytics): coerce non-string page URL in page reports filters - #69767
Conversation
🤖 CI report
|
| File | Size | Δ vs base |
|---|---|---|
exporter/_parent/products/metrics/frontend/MetricsScene.js |
30.1 KiB | 🔺 +4.5 KiB (+17.7%) |
posthog-app/_parent/products/metrics/frontend/MetricsScene.js |
31.2 KiB | 🔺 +4.5 KiB (+17.0%) |
exporter/_parent/products/tracing/frontend/TracingScene.js |
88.9 KiB | 🔺 +2.1 KiB (+2.4%) |
posthog-app/_parent/products/tracing/frontend/TracingScene.js |
89.8 KiB | 🔺 +2.1 KiB (+2.4%) |
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.20 MiB · 22 files | 🔺 +74 B (+0.0%) | ███░░░░░░░ 28.0% of 4.29 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
8.07 MiB · 2,956 files | 🔺 +982 B (+0.0%) | █████████░ 87.2% of 9.25 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 |
| 668 B | src/index.tsx |
Largest files eagerly shipped 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 |
| 164.0 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 |
| 105.7 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 eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
⚠️ Dist folder size — 🔺 +358.2 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1433.69 MiB · 🔺 +358.2 KiB (+0.0%)
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
|
Reviews (1): Last reviewed commit: "fix(web-analytics): coerce non-string pa..." | Re-trigger Greptile |
There was a problem hiding this comment.
Small, contained bug fix with added regression tests, author is on the owning team with STRONG familiarity; the one unresolved inline comment is a stylistic simplification suggestion, not a substantive concern.
- Author wrote 80% of the modified lines and has 93 merged PRs in these paths (familiarity STRONG).
- greptile-apps[bot] reviewed the current head.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 15L, 1F substantive, 20L/2F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1a-trivial (20L, 2F, single-area, fix) |
| stamphog 2.0.0b3 | .stamphog/policy.yml @ 1d5a79e · reviewed head 6426124 |
New commits pushed (delta classified non_trivial_delta) — stamphog approval dismissed; re-review running automatically.
There was a problem hiding this comment.
Small, contained frontend bug fix with tests added; author is on the owning team with strong familiarity, and the sole reviewer comment (a code-quality suggestion) was resolved.
- Author wrote 80% of the modified lines and has 93 merged PRs in these paths (familiarity STRONG).
- 👍 on the PR from chatgpt-codex-connector[bot], greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 15L, 1F substantive, 20L/2F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1a-trivial (20L, 2F, single-area, fix) |
| stamphog 2.0.0b3 | .stamphog/policy.yml @ 7963eba · reviewed head 65e269a |
Problem
The web analytics scene can crash entirely with
TypeError: e.split is not a function(error tracking issue 019f458b-93cc, reported by two customers via support).kea-router JSON-parses query param values, so
?pageURL=123arrives inpageReportsLogicas a number. ThepageUrlreducer is persisted, so the bad value sticks in localStorage. From then on, every recompute of thequeriesselector (any date range or filter change, including on the main/webpage since the logic is connected there) hitscreateUrlPropertyFilter, which callsurl.split('?')on the non-string and throws.Changes
createUrlPropertyFiltercoerces non-string input to a string before parsing. This also heals already-persisted bad values, which a boundary-only fix would leave crashing forever.urlToActionfor/web/page-reportsstringifiessearchParams.pageURLbefore comparing and dispatching, so numeric params never enter state.buildPageUrlOptionsguards itspageUrluse with a string check (same persisted value, different consumer, would crash incleanPathnameForDisplaywith path cleaning enabled).How did you test this code?
Added 3 parameterized cases to the existing
createPageReportsFilterssuite asserting non-string inputs (123,true,null) don't throw. They fail without the coercion and pin the exact prod regression. Full suite (21 tests) passes, andtypescript:checkis green. I did not manually reproduce in a browser.Automatic notifications
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Claude Code session triaging web analytics support tickets. Root cause was confirmed against sourcemapped stacks in error tracking (selector ->
createPageReportsFilters->createUrlPropertyFilter) rather than reproduced locally. Skills invoked: /writing-tests. Chose runtime coercion at both the read path and the router boundary over a reducer-only fix because the value is persisted and a reducer fix alone would leave affected users crashing until they picked a new URL.