{"record":{"id":"6fe9794c0ce38aee","repo":"LGUG2Z/komorebi","slug":"creating-render-factory-failed","errorCode":null,"errorMessage":"creating RENDER_FACTORY failed","messagePattern":"creating RENDER_FACTORY failed","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"komorebi/src/border_manager/border.rs","lineNumber":103,"sourceCode":"\npub struct RenderFactory(ID2D1Factory);\nunsafe impl Sync for RenderFactory {}\nunsafe impl Send for RenderFactory {}\n\nimpl Deref for RenderFactory {\n    type Target = ID2D1Factory;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\n#[allow(clippy::expect_used)]\nstatic RENDER_FACTORY: LazyLock<RenderFactory> = unsafe {\n    LazyLock::new(|| {\n        RenderFactory(\n            D2D1CreateFactory::<ID2D1Factory>(D2D1_FACTORY_TYPE_MULTI_THREADED, None)\n                .expect(\"creating RENDER_FACTORY failed\"),\n        )\n    })\n};\n\nstatic BRUSH_PROPERTIES: LazyLock<D2D1_BRUSH_PROPERTIES> =\n    LazyLock::new(|| D2D1_BRUSH_PROPERTIES {\n        opacity: 1.0,\n        transform: Matrix3x2::identity(),\n    });\n\n/// Apply a new tracked rect to the border on its own message-loop thread.\n/// Updates `window_rect`, calls `set_position`, and re-renders if size/position\n/// changed. Used by both `EVENT_OBJECT_LOCATIONCHANGE` (real window movements)\n/// and `WM_ANIMATE_RECT` (animation-driven movements while the source is cloaked).\n///\n/// SAFETY: caller must ensure `border_pointer` is non-null, points to a live\n/// `Border`, and that we are running on the border's WndProc thread.\nunsafe fn apply_tracked_rect(border_pointer: *mut Border, rect: Rect) {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/LGUG2Z/komorebi/blob/e0709f02bfae4e503bf4640f58ee75ecbbfdbb97/komorebi/src/border_manager/border.rs#L85-L121","documentation":"The border renderer lazily initializes a Direct2D render factory on first use via D2D1CreateFactory in a LazyLock. If COM/D2D1 factory creation fails, the expect panics with this message and the whole komorebi process dies. D2D1CreateFactory fails only in abnormal system conditions since it just allocates a factory object.","triggerScenarios":"First render of the window border triggers LazyLock::new, which calls D2D1CreateFactory::<ID2D1Factory>(D2D1_FACTORY_TYPE_MULTI_THREADED, None); it returns Err when COM is not initialized in the calling thread/apartment, D2D1.dll is missing or corrupted, or on systems where Direct2D/DirectX components are unavailable (e.g. Server Core, broken graphics drivers).","commonSituations":"Running komorebi on Windows Server Core or a stripped VM without Direct2D/DirectX runtime components; corrupted Windows graphics stack after a failed update; running in an environment where COM initialization failed; out-of-memory during factory creation.","solutions":["Verify Windows has Direct2D/DirectX runtime components installed (install Desktop Experience / graphics feature on Server SKUs, run sfc /scannow to repair system files)","Update GPU drivers and confirm D2D1.dll exists in System32","Ensure the calling thread is COM-initialized (CoInitializeEx) before the factory is created if used off the main thread","Update komorebi to the latest version; report as a bug with Windows version details if the system is a normal desktop install","As a workaround, disable the border feature (komorebic border disable) so RENDER_FACTORY is never initialized"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// PowerShell: verify D2D1.dll present before running komorebi\nif (-not (Test-Path \"$env:SystemRoot\\System32\\d2d1.dll\")) {\n  throw \"Direct2D runtime missing; install Desktop Experience / repair Windows\"\n}","typeGuard":null,"tryCatchPattern":"// Make factory creation fallible and degrade gracefully\nstatic RENDER_FACTORY: LazyLock<Result<RenderFactory, String>> = LazyLock::new(|| {\n    unsafe { D2D1CreateFactory::<ID2D1Factory>(D2D1_FACTORY_TYPE_MULTI_THREADED, None) }\n        .map(RenderFactory)\n        .map_err(|e| e.to_string())\n});\n// at use site: if let Err(e) = *RENDER_FACTORY { log::warn!(\"borders unavailable: {e}\"); return; }","preventionTips":["Keep Direct2D/DirectX runtime and GPU drivers up to date","Avoid running komorebi on Server Core / graphics-less SKUs","Initialize COM on threads that touch D2D","Disable border rendering on machines where D2D is known to be broken"],"tags":["windows","direct2d","com","panic","graphics"],"backgroundTag":"module-init-failed","analyzedSha":"e0709f02bfae4e503bf4640f58ee75ecbbfdbb97","analyzedAt":"2026-09-06T07:08:05.107Z","contentChangedAt":"2026-09-06T07:08:05.107Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}