SvelteKit + Sentry error reports show wrong page URL during client-side navigation errors.
A TypeError (Cannot read properties of undefined (reading 'length')) was reported by Sentry with transaction: /teams and url: http://localhost:5183/teams, but the stack trace pointed to a completely different component (t/+page.svelte) that renders at /t. The teams page component has no .length access at all, making the error report appear impossible.
Root cause has two parts:
Sentry URL mismatch: When an error occurs during a SvelteKit client-side page transition, Sentry's
mechanism: onunhandledrejectioncaptures the browser's current URL at reporting time (the navigation destination), not the URL where the error-throwing component was mounted. The stack trace file path is the authoritative indicator of the actual crash location.TypeScript
ascast providing false safety: The page server loader usedconst data = res.data as { items: T[]; total: number }then returnedtags: data.items. Theascast is compile-time only; if the API response shape differs at runtime (proxy returning non-JSON 200, API contract drift),data.itemsisundefined. The Svelte template then crashes on{#if data.tags.length > 0}.
Diagnosing the Sentry mismatch:
- When
mechanism: onunhandledrejectionappears in a SvelteKit Sentry report, trust the stack trace file path over the URL/transaction fields - The URL shows where the browser ended up, not where the error originated
- This happens because SvelteKit page transitions are async; component destruction/creation during navigation can throw after the URL has already changed
Fixing the runtime safety gap:
In the page server loader, mark response fields as optional and apply fallbacks:
// Before (unsafe): as cast trusts runtime shape
const data = res.data as { items: T[]; total: number };
return { tags: data.items, total: data.total };
// After (safe): optional fields + nullish coalescing
const body = res.data as { items?: T[]; total?: number };
return { tags: body.items ?? [], total: body.total ?? 0 };In the Svelte template, use optional chaining:
<!-- Before: crashes if data.tags is undefined -->
{#if data.tags.length > 0}
<!-- After: safely handles undefined -->
{#if data.tags?.length}Both defenses are needed: the loader fix prevents the bug; the template fix survives if the loader contract is violated by future changes.