Hidden Assumptions in analytics
12 assumptions this code never checks · 4 critical · spanning Shape, Environment, Domain, Temporal, Ordering, Scale, Resource, Contract
Every codebase relies on things it never checks. Most of them are routine. CodeSea looked at plausible/analytics and picked out the few most likely to cause trouble. The full list is just below.
Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".
If event target is null, undefined, or doesn't have contains method, modal throws TypeError and breaks click-outside-to-close functionality
Circular references in changeset data cause infinite recursion and stack overflow during audit logging, potentially crashing the process
In server-side rendering or non-browser environments, accessing document.body.style throws reference error and prevents modal rendering
Show everything (9 more)
Cross-origin fetch to https://plausible.io/changes.txt will always succeed and return valid text response - assumes network availability, CORS headers, and server uptime
If this fails: Network failures or CORS issues cause silent Promise rejection, leaving changelog notification in inconsistent state with no error handling
assets/js/app.js:changelogNotification
Browser names from user agent parsing exactly match BROWSER_ICONS keys - assumes consistent string formatting between user agent parser and icon mapping
If this fails: Unrecognized browser names fall back to 'fallback.svg' which may not exist, causing broken image icons in device reports
assets/js/dashboard/stats/devices/index.js:browserIconFor
localStorage.lastChangelogUpdate contains valid timestamp number that can be parsed - assumes previous successful fetch stored valid Date.getTime() value
If this fails: Invalid or corrupted timestamp values cause NaN comparisons, potentially showing changelog notification incorrectly or never
assets/js/app.js:showChangelogNotification
parseSearch(location.search) returns object with expected filter structure before postProcessFilters runs - assumes URL parsing happens before filter processing
If this fails: Malformed URL search params could pass undefined or invalid filter arrays to postProcessFilters, causing dashboard state corruption
assets/js/dashboard/dashboard-state-context.tsx:useMemo
Goal names in localStorage keys are URL-safe and don't contain special characters - assumes goal names from API responses are sanitized for storage key usage
If this fails: Goal names with special characters create invalid localStorage keys, causing prop key storage/retrieval to fail silently for those goals
assets/js/dashboard/stats/behaviours/index.js:STORAGE_KEYS.getForPropKeyForGoal
Window innerWidth is available and returns valid number - assumes browser window object exists with width measurement capability
If this fails: In headless or server environments where window.innerWidth is undefined, modal sizing falls back to DEFAULT_WIDTH but resize handler may throw errors
assets/js/dashboard/stats/modals/modal.js:DEFAULT_WIDTH
ListReport component expects getFilterInfo to return object with specific shape {prefix: string, filter: [string, string, string[]]} - assumes consistent filter structure contract
If this fails: If getFilterInfo returns different structure, ListReport filter application fails silently or throws errors when constructing dashboard queries
assets/js/dashboard/stats/pages/index.js:getFilterInfo
BUILD_EXTRA global is defined at compile time and controls conditional module loading - assumes build system sets this flag correctly
If this fails: If BUILD_EXTRA is undefined, maybeRequire() behavior is unpredictable and could break funnel functionality in production builds
assets/js/dashboard/stats/behaviours/index.js:BUILD_EXTRA
Modal cleanup happens in exact reverse order of setup - assumes removeEventListener calls match addEventListener pairs from componentDidMount
If this fails: If component unmounts during event handling or if event listeners were modified elsewhere, cleanup may miss listeners causing memory leaks
assets/js/dashboard/stats/modals/modal.js:componentWillUnmount
See the full structural analysis of analytics: the pipeline, data models, and system behavior that put these assumptions in context.
Full analysis of plausible/analytics →Frequently Asked Questions
What does analytics assume that could break in production?
The one most likely to cause trouble: Mouse events have target property that points to DOM elements that respond to contains() method - assumes e.target is a node and this.node.current is a DOM element with contains method If this fails, If event target is null, undefined, or doesn't have contains method, modal throws TypeError and breaks click-outside-to-close functionality
How many hidden assumptions does analytics have?
CodeSea found 12 assumptions analytics relies on but never validates, 4 of them critical, spanning Shape, Environment, Domain, Temporal, Ordering, Scale, Resource, Contract. Most are routine — the analysis flags the two or three most likely to actually bite.
What is a hidden assumption?
Something the code depends on but never checks: a data shape, an ordering, an environment condition, a scale limit, or a contract with another service. It holds until the world it runs in changes, then fails silently.