Skip to main content
Admin Modules

Client-Side JavaScript Audit

F12 console error analysis — event listener leaks, timer leaks, null crashes, and View Transitions issues across all 122 page scripts

February 28, 2026

Client-Side JavaScript Audit

Full source code audit of all 122 .astro files with client-side <script> blocks, searching for patterns that produce browser DevTools (F12) console errors. Covers admin pages, playground, command center, dashboard, and public pages.

Findings Summary

IssueCountSeverity
Global event listener leaks11 filesCritical
Timer/interval leaks13 filesCritical
Missing null checks (querySelector)9+ filesError
Non-null assertions (getElementById)10+ files (~80 instances)Warning
fetch() without try/catch16 files (~25 calls)Warning
No route guard on astro:page-load85 pagesWarning
DOMContentLoaded violations0Clear

Event Listener Leaks

The Problem

document.addEventListener('keydown', handler) inside is:inline scripts re-executes on every View Transitions navigation. Each navigation adds another copy of the same handler. After 5 navigations, you have 5 duplicate keydown handlers all firing.

Similarly, handlers added inside astro:page-load callbacks accumulate because the callback fires on every navigation.

Affected Files

FileLine(s)Leak
admin/edit.astro3159, 6173, 61853 keydown handlers per navigation
admin/pipeline.astro1460Ctrl+S stacks
admin/homelab.astro2155Escape stacks
admin/mm-terminal.astro184Escape stacks
admin/docs-hub.astro260Escape stacks
admin/dashboard-profiles/edit/[id].astro876Escape stacks
admin/chat.astro1532Ctrl+N persists globally
admin/workbench.astro4033Ctrl+N persists globally
admin/personal.astro1435Ctrl+N persists globally
admin/probe-studio.astro1340Global click handler stacks
admin/content-lab.astro658+querySelectorAll handlers stack

Fix Pattern

Use a dedup flag or named function with cleanup:

// Option A: dedup flag
if (!window.__editKeydownBound) {
  window.__editKeydownBound = true;
  document.addEventListener('keydown', handleKeydown);
}

// Option B: cleanup in astro:before-swap
document.addEventListener('astro:before-swap', () => {
  document.removeEventListener('keydown', handleKeydown);
}, { once: true });

Timer/Interval Leaks

The Problem

setInterval() or recursive setTimeout() that keeps running after the user navigates away. The old timer fires on a different page, trying to update DOM elements that don’t exist.

No Cleanup At All (7 pages)

FileIntervalsContext
404.astro2Animation timers
playground/build-swarm.astro5Simulation timers
playground/monitoring.astro2Demo timers
playground/infrastructure.astro1Animation timer
command/space.astro3Animation timers
command/portal.astro1Animation timer
projects/services.astro1Polling timer

Partial Cleanup (6 pages)

These have astro:before-swap cleanup but miss some timers:

FileMissed TimerWhat’s Cleaned
admin/build.astroBS.pollTimerNothing
admin/edit.astroS.autoSaveTimerNothing
admin/rag.astroollamaPollTimerpollTimer
admin/jobs.astroretryTimer, local pollpollInterval
admin/servers/index.astroanonymous intervalN/A (no VT layout)

Fix Pattern

// Store all timers
let pollTimer, retryTimer;

// Cleanup ALL timers on navigation
document.addEventListener('astro:before-swap', () => {
  clearInterval(pollTimer);
  clearInterval(retryTimer);
}, { once: true });

Null Reference Crashes

querySelector Without Null Checks

Direct property access on querySelector() results — crashes with TypeError: Cannot read properties of null.

FileLineCode
admin/index.astro1810.querySelector('.filter-btn.active').dataset.filter
admin/index.astro1931.querySelector('.table-container').scrollIntoView(...)
admin/pipeline.astro616, 621.querySelector('.pipe-stage').classList
admin/network-map.astro514, 521, 535querySelector('input:checked').value
admin/security.astro491-494.querySelector('.sec-stat-value').textContent

getElementById Non-null Assertions

TypeScript ! assertions are erased at runtime — no actual null check:

  • admin/chat.astro — 15 instances
  • admin/workbench.astro — 15+
  • admin/settings.astro — 14
  • admin/build-swarm-public-v3.astro — 10+

Fix Pattern

// Use optional chaining
document.querySelector('.filter-btn.active')?.dataset?.filter;

// Or assign with guard
const el = document.getElementById('myEl');
if (!el) return;
el.textContent = 'value';

Unhandled Fetch Errors

16 files have await fetch() without try/catch. Network errors produce unhandled promise rejections.

Files: admin/bland.astro, admin/build-swarm.astro, admin/cloudflare/dns.astro, admin/edit.astro, admin/elevenlabs.astro, admin/email.astro, admin/index.astro, admin/linkedin-studio.astro, admin/network-map.astro, admin/pipeline.astro, admin/servers/index.astro, admin/settings.astro, admin/twilio.astro, admin/vapi.astro, admin/workbench.astro, dashboard/index.astro

Missing Route Guards

85 pages have astro:page-load handlers with fetches or timers but no window.location.pathname check. Their initialization logic fires on every View Transitions navigation, even when the user is on a completely different page.

Top offenders:

FileActions Firing
command/build.astro42
admin/workbench.astro28
admin/probe-studio.astro15
dashboard/index.astro14
playground/build-swarm.astro13

Fix Pattern

document.addEventListener('astro:page-load', () => {
  if (!window.location.pathname.startsWith('/admin/health')) return;
  // ... rest of init
});

Pages With Proper Cleanup

These pages correctly implement cleanup and serve as reference:

PagePattern Used
admin/deployments.astroastro:before-swap + { once: true }
admin/ollama.astroMultiple timers all in cleanup
admin/playground.astrodestroyed flag pattern
admin/workbench.astroCleanup for timers + AbortController
admin/health.astroTimer cleanup
admin/system-test.astroDedup guard + route check

Fix Priority

  1. Timer leaks in admin pages — cause real network requests to wrong endpoints
  2. Global keydown leaks — cause duplicate keyboard shortcuts firing
  3. Null querySelector crashes — cause visible F12 errors
  4. Route guards — low effort, high impact
  5. Non-null assertions — lower priority (only crash if HTML changes)
  6. fetch error handling — lowest (only affects network failures)
ItemValue
Audit date2026-02-28
Files scanned122 .astro files with script blocks
MethodSource code pattern analysis
Vault referenceinfrastructure/24-CLIENT-SIDE-AUDIT-2026-02-28.md
Previous auditsSite Health Test, System Test
admintestingauditjavascriptview-transitionsconsole-errors