{"record":{"id":"2d2f68efa10e297b","repo":"iced-rs/iced","slug":"create-event-loop","errorCode":null,"errorMessage":"Create event loop","messagePattern":"Create event loop","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"winit/src/lib.rs","lineNumber":83,"sourceCode":"use std::mem::ManuallyDrop;\nuse std::slice;\nuse std::sync::Arc;\n\n/// Runs a [`Program`] with the provided settings.\npub fn run<P>(program: P) -> Result<(), Error>\nwhere\n    P: Program + 'static,\n    P::Theme: theme::Base,\n{\n    use winit::event_loop::EventLoop;\n\n    let boot_span = debug::boot();\n    let settings = program.settings();\n    let window_settings = program.window();\n\n    let event_loop = EventLoop::with_user_event()\n        .build()\n        .expect(\"Create event loop\");\n\n    let backend_settings = backend::Settings::from(&settings);\n    let renderer_settings = renderer::Settings::from(&settings);\n    let display_handle = event_loop.owned_display_handle();\n\n    let (proxy, worker) = Proxy::new(event_loop.create_proxy());\n\n    #[cfg(feature = \"debug\")]\n    {\n        let proxy = proxy.clone();\n\n        debug::on_hotpatch(move || {\n            proxy.send_action(Action::Reload);\n        });\n    }\n\n    let mut runtime = {\n        let executor = P::Executor::new().map_err(Error::ExecutorCreationFailed)?;","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/iced-rs/iced/blob/2cffa99b395d84fe469b44dccb56bbacd2f1a157/winit/src/lib.rs#L65-L101","documentation":"This panic occurs when winit's EventLoop::with_user_event().build() returns an error inside iced_winit::run (winit/src/lib.rs:81-83), before any window exists. EventLoopError means the platform could not initialize its event loop: on Linux there is no connection to a display server (no X11 via DISPLAY and no Wayland via WAYLAND_DISPLAY), and on any platform creating a second event loop in the same process fails (RecreationAttempt). Because iced unwraps with .expect(\"Create event loop\"), the application dies at startup with this message.","triggerScenarios":"Running the binary where no display server is reachable: Docker containers, CI runners, systemd services, cron — DISPLAY and WAYLAND_DISPLAY unset; SSH sessions without X11 forwarding; a Wayland session whose compositor socket under $XDG_RUNTIME_DIR is gone; calling iced::run (or otherwise constructing an EventLoop) a second time in one process, e.g. two invocations in the same integration-test binary; on macOS, initializing the event loop off the main thread.","commonSituations":"GUI apps that also run in CI or containers without Xvfb; test harnesses that boot the full iced runtime per #[test] function; running the GUI binary over plain ssh; distro/minimal images where libxcb/libxkbcommon-x11 are missing so the X11 connect fails; switching sessions between X11 and Wayland with stale environment variables.","solutions":["Provide a display: in CI/Docker run under `xvfb-run -a cargo test` / `xvfb-run -a ./app`; over SSH use `ssh -X` or `ssh -Y`, or set DISPLAY to a reachable X server.","On Wayland ensure WAYLAND_DISPLAY points at a live socket (check `ls $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY`); on X11 verify with `echo $DISPLAY` and `xdpyinfo`.","Never create the event loop twice in one process: call iced::run exactly once from main(); in integration tests run one app per test binary, spawn each case as a child process, or test UI logic with iced's headless runtime APIs instead of the full shell.","If the failure is a missing library rather than a missing display, install the X11 stack (libxcb, libxkbcommon, libxkbcommon-x11) or build iced with only the `wayland` feature to drop the X11 dependency entirely.","If you need no window at all (render to an image, offscreen compositing), use wgpu headlessly or iced's headless rendering support instead of iced_winit::run."],"exampleFix":"// before — panics with \"Create event loop\" in headless CI/containers\nfn main() -> iced::Result {\n    iced::run(\"Todo\", Todos::update, Todos::view)\n}\n\n// after — fail fast with an actionable message instead of a winit panic\nfn main() -> iced::Result {\n    #[cfg(target_os = \"linux\")]\n    if std::env::var(\"DISPLAY\").is_err() && std::env::var(\"WAYLAND_DISPLAY\").is_err() {\n        eprintln!(\"no display server found: set DISPLAY/WAYLAND_DISPLAY or run under xvfb-run\");\n        std::process::exit(64);\n    }\n    iced::run(\"Todo\", Todos::update, Todos::view)\n}","handlingStrategy":"validation","validationCode":"// Run before calling iced::run / any winit API on Linux\nfn display_available() -> bool {\n    std::env::var(\"DISPLAY\").is_ok() || std::env::var(\"WAYLAND_DISPLAY\").is_ok()\n}\n\nfn main() -> iced::Result {\n    #[cfg(target_os = \"linux\")]\n    if !display_available() {\n        eprintln!(\"no display server: set DISPLAY/WAYLAND_DISPLAY or run under xvfb-run\");\n        std::process::exit(64);\n    }\n    iced::run(\"App\", Update::new, View::new)\n}\n\n# CI equivalent: xvfb-run -a cargo test -- --nocapture","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call iced::run (and any EventLoop construction) exactly once per process, from the main thread.","Fail fast at startup: check DISPLAY/WAYLAND_DISPLAY on Linux and print a remediation hint instead of letting winit panic.","In Dockerfiles and CI, install xvfb and launch via xvfb-run; document the display requirement in the README.","Test UI logic with iced's runtime/headless APIs rather than booting the full event loop per test function."],"tags":["rust","iced","winit","linux","x11","wayland","headless","ci","panic","startup"],"backgroundTag":"cannot-open-display","analyzedSha":"2cffa99b395d84fe469b44dccb56bbacd2f1a157","analyzedAt":"2026-08-16T19:41:49.083Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}