{"record":{"id":"dbfd81951568b17f","repo":"linebender/druid","slug":"error-registering-class","errorCode":null,"errorMessage":"Error registering class","messagePattern":"Error registering class","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"druid-shell/src/backend/windows/application.rs","lineNumber":98,"sourceCode":"            .is_ok()\n        {\n            let class_name = CLASS_NAME.to_wide();\n            let icon = unsafe { LoadIconW(GetModuleHandleW(0 as LPCWSTR), MAKEINTRESOURCEW(1)) };\n            let wnd = WNDCLASSW {\n                style: 0,\n                lpfnWndProc: Some(window::win_proc_dispatch),\n                cbClsExtra: 0,\n                cbWndExtra: 0,\n                hInstance: 0 as HINSTANCE,\n                hIcon: icon,\n                hCursor: 0 as HCURSOR,\n                hbrBackground: ptr::null_mut(), // We control all the painting\n                lpszMenuName: 0 as LPCWSTR,\n                lpszClassName: class_name.as_ptr(),\n            };\n            let class_atom = unsafe { RegisterClassW(&wnd) };\n            if class_atom == 0 {\n                panic!(\"Error registering class\");\n            }\n        }\n        Ok(())\n    }\n\n    pub fn add_window(&self, hwnd: HWND) -> bool {\n        self.state.borrow_mut().windows.insert(hwnd)\n    }\n\n    pub fn remove_window(&self, hwnd: HWND) -> bool {\n        self.state.borrow_mut().windows.remove(&hwnd)\n    }\n\n    pub fn run(self, _handler: Option<Box<dyn AppHandler>>) {\n        unsafe {\n            // Handle windows messages.\n            //\n            // NOTE: Code here will not run when we aren't in charge of the message loop. That","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/linebender/druid/blob/0f8b1195e4e073f9597f2865299c3d18f8e4005f/druid-shell/src/backend/windows/application.rs#L80-L116","documentation":"During windows backend application initialization (Application::init), the win32 window class is registered with RegisterClassW. A return value of 0 means class registration failed, and the code panics with this message. Common win32 error codes behind it are ERROR_CLASS_ALREADY_EXISTS (1410) and access/parameter errors.","triggerScenarios":"Calling Application::init (or new()) twice in the same process so the same class name is registered twice; RegisterClassW failing due to an invalid WNDCLASSW field or the process lacking rights to register classes (restricted desktop/session, some service or sandboxed environments).","commonSituations":"Unit tests or examples that initialize the druid-shell Application more than once per process; running under restricted environments (Windows Service Session 0, some CI runners, AppContainer) where class registration is denied; conflicts from another framework registering an identically named class.","solutions":["Ensure Application::init is called exactly once per process; guard with std::sync::Once if initialization may race.","Call win32 GetLastError / FormatMessage around the failure (or wrap RegisterClassW) to see the actual error code and confirm whether it's ERROR_CLASS_ALREADY_EXISTS.","If double-registration is intentional in tests, ignore error 1410 instead of panicking, or register with a unique class name per process.","Run the app in an interactive user session rather than a service/sandboxed context, and check that no DLL has already registered the same class name."],"exampleFix":"// before\nlet class_atom = unsafe { RegisterClassW(&wnd) };\nif class_atom == 0 {\n    panic!(\"Error registering class\");\n}\n// after: tolerate double init\nlet class_atom = unsafe { RegisterClassW(&wnd) };\nif class_atom == 0 {\n    let err = unsafe { GetLastError() };\n    if err != ERROR_CLASS_ALREADY_EXISTS {\n        panic!(\"Error registering class: {err}\");\n    }\n}","handlingStrategy":"validation","validationCode":"// before init, verify class not already registered and single init\nuse std::sync::Once;\nstatic INIT: Once = Once::new();\nINIT.call_once(|| Application::new().unwrap());","typeGuard":null,"tryCatchPattern":"// init panics; run it in a check that tolerates double-init\nstd::panic::catch_unwind(Application::init)\n    .map_err(|_| anyhow!(\"Application::init failed (already initialized or restricted session)\"))?;","preventionTips":["Call Application::init/new exactly once per process (use std::sync::Once).","Don't run druid apps inside services, AppContainers, or restricted sessions without verifying window-class registration rights.","Avoid third-party DLLs that may register a conflicting class name.","Capture GetLastError around win32 calls when debugging startup failures."],"tags":["windows","win32","init","panic"],"backgroundTag":"module-init-failed","analyzedSha":"0f8b1195e4e073f9597f2865299c3d18f8e4005f","analyzedAt":"2026-09-10T14:27:34.582Z","contentChangedAt":"2026-09-10T14:27:34.582Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}