{"record":{"id":"8b88cdd084df42b3","repo":"bevyengine/bevy","slug":"failed-to-build-event-loop","errorCode":null,"errorMessage":"Failed to build event loop","messagePattern":"Failed to build event loop","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/bevy_winit/src/lib.rs","lineNumber":137,"sourceCode":"        }\n\n        #[cfg(target_os = \"windows\")]\n        {\n            use winit::platform::windows::EventLoopBuilderExtWindows;\n            event_loop_builder.with_any_thread(self.run_on_any_thread);\n        }\n\n        #[cfg(target_os = \"android\")]\n        {\n            use winit::platform::android::EventLoopBuilderExtAndroid;\n            let msg = \"Bevy must be setup with the #[bevy_main] macro on Android\";\n            event_loop_builder\n                .with_android_app(bevy_android::ANDROID_APP.get().expect(msg).clone());\n        }\n\n        let event_loop = event_loop_builder\n            .build()\n            .expect(\"Failed to build event loop\");\n\n        let event_loop_proxy = event_loop.create_proxy();\n\n        // Wake up the event loop when `Ctrl+C` is received so that the app can\n        // exit even while idle in a reactive update mode\n        #[cfg(any(all(unix, not(target_os = \"horizon\")), windows))]\n        {\n            let event_loop_proxy = event_loop_proxy.clone();\n            bevy_app::TerminalCtrlCHandlerPlugin::register_exit_handler(move || {\n                let _ = event_loop_proxy.send_event(WinitUserEvent::WakeUp);\n            });\n        }\n\n        app.init_resource::<WinitMonitors>()\n            .init_resource::<WinitSettings>()\n            .insert_resource(DisplayHandleWrapper(event_loop.owned_display_handle()))\n            .insert_resource(EventLoopProxyWrapper(event_loop_proxy))\n            .add_message::<RawWinitWindowEvent>()","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_winit/src/lib.rs#L119-L155","documentation":"During startup bevy_winit builds the platform event loop with winit's EventLoopBuilder and .expect(\"Failed to build event loop\") — any winit failure here aborts the process before the app runs. winit fails when it cannot connect to a display server (X11/Wayland), platform libraries are missing, or platform integration is misconfigured (e.g. Android without the app handle set up by #[bevy_main]).","triggerScenarios":"Running a windowed Bevy app on a headless Linux machine or CI runner with no $DISPLAY/WAYLAND_DISPLAY; SSH sessions without X forwarding; missing libxkbcommon/X11/Wayland client libraries; Android builds not using #[bevy_main]; sandboxed environments denying display sockets.","commonSituations":"CI pipelines launching integration tests that accidentally include DefaultPlugins; deploying a game binary to a server; minimal container images without graphics runtime libs; fresh Linux installs without mesa/X11; WSL without WSLg.","solutions":["Run inside a graphical session, or forward one over SSH (ssh -X) / WSLg on Windows.","On headless CI, use a virtual framebuffer: xvfb-run ./your_app, or install the X11/Wayland client libraries (libxkbcommon, libx11, libwayland) if they are missing.","For genuinely headless workloads, build without the windowing plugins or configure WindowPlugin with primary_window: None and use a headless renderer setup.","On Android, enter via #[bevy_main] so the android app handle is available to the event loop builder.","Check backend environment variables (e.g. WGPU_BACKEND, WINIT_UNIX_BACKEND) for values unsupported on the machine."],"exampleFix":"# before (headless server / CI)\n./my_bevy_game   # panics: Failed to build event loop\n\n# after\nxvfb-run -a ./my_bevy_game   # virtual display for windowed apps on headless machines","handlingStrategy":"validation","validationCode":"#[cfg(target_os = \"linux\")]\nfn display_available() -> bool {\n    std::env::var(\"DISPLAY\").is_ok() || std::env::var(\"WAYLAND_DISPLAY\").is_ok()\n}\n\n#[cfg(target_os = \"linux\")]\nfn main() {\n    if !display_available() {\n        eprintln!(\"no display server found; set DISPLAY/WAYLAND_DISPLAY or run under xvfb-run\");\n        std::process::exit(1);\n    }\n    my_game::run();\n}","typeGuard":null,"tryCatchPattern":"// Startup abort, not a Result: validate the environment before App::new().run().\n// In CI, choose headless plugins or wrap execution with `xvfb-run` instead of catching.","preventionTips":["Check DISPLAY/WAYLAND_DISPLAY (Linux) before launching windowed builds.","Keep a separate headless/CI feature set that excludes bevy_winit windowing.","Install X11/Wayland client libs in minimal containers that must run windowed apps.","On Android always use #[bevy_main]."],"tags":["rust","bevy","winit","windowing","startup","linux","headless"],"backgroundTag":"event-loop-creation-failed","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}