{"record":{"id":"6db2db6515254908","repo":"denoland/deno","slug":"desktop-mode-enabled","errorCode":null,"errorMessage":"desktop mode enabled","messagePattern":"desktop mode enabled","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"runtime/ops/desktop.rs","lineNumber":760,"sourceCode":"  }\n}\n\nstruct EventTargetSetup {\n  brand: v8::Global<v8::Value>,\n  set_event_target_data: v8::Global<v8::Value>,\n}\n\n#[op2]\nimpl BrowserWindow {\n  #[constructor]\n  fn new(\n    state: &OpState,\n    scope: &mut v8::PinScope<'_, '_>,\n    #[scoped] options: Option<BrowserWindowOptions>,\n  ) -> v8::Global<v8::Value> {\n    let api = state\n      .try_borrow::<Arc<dyn DesktopApi>>()\n      .expect(\"desktop mode enabled\")\n      .clone();\n\n    // Use the initial window if this is the first BrowserWindow,\n    // otherwise create a new one.\n    let window_id = state\n      .try_borrow::<InitialWindowId>()\n      .and_then(|iw| iw.0.lock().unwrap().take())\n      .unwrap_or_else(|| {\n        let width = options.as_ref().and_then(|o| o.width).unwrap_or(800);\n        let height = options.as_ref().and_then(|o| o.height).unwrap_or(600);\n        let frameless =\n          options.as_ref().and_then(|o| o.frameless).unwrap_or(false);\n        let no_activate = options\n          .as_ref()\n          .and_then(|o| o.no_activate)\n          .unwrap_or(false);\n        let transparent_titlebar = options\n          .as_ref()","sourceCodeStart":742,"sourceCodeEnd":778,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/runtime/ops/desktop.rs#L742-L778","documentation":"BrowserWindow is Deno's desktop API class, implemented in runtime/ops/desktop.rs. Its constructor fetches Arc<dyn DesktopApi> from OpState with expect(\"desktop mode enabled\"); that state is only installed by the desktop runtime (cli/rt_desktop, used by `deno desktop` / `deno compile --desktop`). Constructing BrowserWindow under plain `deno run` panics in native code and aborts the process — the panic cannot be caught with JS try/catch.","triggerScenarios":"`new BrowserWindow({ width: 800, height: 600 })` executed in a normal `deno run main.ts` process (or any non-desktop runtime like `deno eval`, `deno test`, `deno serve`), typically because shared code imported by a desktop app was also executed outside it.","commonSituations":"Importing a module that creates the window at top level into a test or a server build; running the desktop entry with `deno run` during development instead of `deno run` under the desktop runtime; unit tests importing component modules that instantiate windows; code shared between CLI and desktop targets.","solutions":["Run the app through the desktop runtime: `deno desktop <entry>` during development, or build with `deno compile --desktop` and run the produced binary.","Move `new BrowserWindow(...)` behind an explicit entry point used only by the desktop app, not into shared/imported modules with side effects.","Gate desktop construction with a runtime flag you control (e.g. a global set only in the desktop entry) so tests and CLI builds never reach the constructor.","For unit tests, mock/inject the window factory instead of constructing the real class."],"exampleFix":"// before (runs under `deno run` -> panic: desktop mode enabled)\nexport const win = new BrowserWindow({ width: 800, height: 600 });\n\n// after: construct only when launched by the desktop runtime\nif (globalThis.__DESKTOP_ENTRY__) {\n  const win = new BrowserWindow({ width: 800, height: 600 });\n}","handlingStrategy":"validation","validationCode":"// set this only in the desktop entry, before importing shared modules\nglobalThis.__DESKTOP_ENTRY__ = true;\n\n// shared module\nif (globalThis.__DESKTOP_ENTRY__) {\n  const win = new BrowserWindow({ width: 800, height: 600 });\n}","typeGuard":"const isDesktopRuntime = () => globalThis.__DESKTOP_ENTRY__ === true;","tryCatchPattern":null,"preventionTips":["Only construct BrowserWindow in processes launched by `deno desktop` or built with `deno compile --desktop`.","Never construct windows at module top level in shared code; defer to an init function in the desktop entry.","Remember this failure is a Rust panic — JS try/catch cannot intercept it, so prevention is the only defense."],"tags":["desktop","browserwindow","runtime-mode","panic","desktop-runtime"],"backgroundTag":"desktop-mode-not-enabled","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}