{"record":{"id":"711b59b6fca7b4c3","repo":"eythaann/Seelen-UI","slug":"current-monitor-not-found","errorCode":null,"errorMessage":"Current monitor not found","messagePattern":"Current monitor not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/ui/svelte/fancy-toolbar/state/system.svelte.ts","lineNumber":9,"sourceCode":"import { FancyToolbarSide } from \"@seelen-ui/lib/types\";\nimport { currentMonitorId, monitors, mousePos, virtualDesktop } from \"./getters.svelte.ts\";\n\nexport { virtualDesktop };\n\nconst _currentMonitor = $derived.by(() => {\n  const monitor = monitors.value.find((m) => m.id === currentMonitorId);\n  if (!monitor) {\n    throw new Error(\"Current monitor not found\");\n  }\n  return monitor;\n});\n\nconst _mouseAtEdge = $derived.by((): FancyToolbarSide | null => {\n  const box = _currentMonitor.rect;\n  const x = mousePos.value[0];\n  const y = mousePos.value[1];\n\n  if (x < box.left || x > box.right || y < box.top || y > box.bottom) {\n    return null;\n  }\n\n  if (y === box.top) {\n    return FancyToolbarSide.Top;\n  }\n\n  if (y === box.bottom - 1) {","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/eythaann/Seelen-UI/blob/dee4aaa94066c5d0888ab25554864862fc47be15/src/ui/svelte/fancy-toolbar/state/system.svelte.ts#L1-L27","documentation":"The fancy-toolbar widget derives its current monitor by finding, in the `monitors` signal, the entry whose id matches `currentMonitorId`. If no monitor matches, `$derived.by` throws `Current monitor not found`. Since this runs inside a reactive derivation, the whole toolbar render fails until the monitor id resolves.","triggerScenarios":"`monitors.value` has not been populated yet (initial load before the backend sends the monitor list) or `currentMonitorId` refers to a monitor that was unplugged/changed id (display hot-plug, monitor re-enumeration, sleep/resume).","commonSituations":"Toolbar starting up before the first `MonitorsChanged` event arrives; user unplugs an external display the toolbar was attached to; Windows display reconfiguration changing monitor ids.","solutions":["Guard the lookup: fall back to the first monitor or skip the derivation when not found instead of throwing.","Ensure `monitors` and `currentMonitorId` signals are initialized (LazySignal `.init()` awaited) before reactive UI consumes them.","Subscribe to monitor-change events and re-evaluate; verify the toolbar webview restarts/re-syncs on `MonitorsChanged`."],"exampleFix":"// before\nconst monitor = monitors.value.find((m) => m.id === currentMonitorId);\nif (!monitor) throw new Error(\"Current monitor not found\");\n// after\nconst monitor = monitors.value.find((m) => m.id === currentMonitorId)\n  ?? monitors.value[0];\nif (!monitor) return null;","handlingStrategy":"fallback","validationCode":"const monitor = monitors.value.find((m) => m.id === currentMonitorId);\nconst isMonitorReady = Boolean(monitor); // check before consuming the derived monitor","typeGuard":"function monitorExists(id: string): boolean {\n  return monitors.value.some((m) => m.id === id);\n}","tryCatchPattern":"// wrap consumers of the derived monitor\ntry {\n  renderToolbar(_currentMonitor);\n} catch (e) {\n  if ((e as Error).message === \"Current monitor not found\") renderSkeleton();\n  else throw e;\n}","preventionTips":["Await LazySignal init for `monitors` before mounting UI that derives from it.","Handle monitor hot-plug events and re-resolve currentMonitorId.","Design derivations to return null/safe defaults for transient states instead of throwing."],"tags":["monitors","race-condition","svelte","reactive-state"],"backgroundTag":"monitor-not-found","analyzedSha":"dee4aaa94066c5d0888ab25554864862fc47be15","analyzedAt":"2026-09-03T10:20:37.842Z","contentChangedAt":"2026-09-03T10:20:37.842Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}