linebender/druid · error

There is no globally active Application

Error message

There is no globally active Application

What it means

Application::global() returns the process-wide active druid-shell Application and panics (via expect) when none exists. A global Application only exists between Application::new() and the end of Application::run(); calling global() outside that window panics with this message instead of returning Result.

Solutions

  1. Call `Application::new()` (on the main thread) before any code path that uses Application::global().
  2. Use `Application::try_global()` and handle None instead of panicking, when global availability is uncertain.
  3. In tests, initialize an Application in the test setup, or avoid APIs that require a global app (use mock abstractions).
  4. Ensure all window/clipboard work happens between new() and run() returning, on the main thread.

Example fix

// before
fn open_window() -> WindowHandle {
    WindowBuilder::new(Application::global()).build().unwrap()
}

// after
fn open_window(app: &Application) -> Result<WindowHandle, Error> {
    WindowBuilder::new(app.clone()).build()
}
// or: Application::try_global().ok_or_else(|| anyhow!("no active application"))?
Defensive patterns

Strategy: fallback

Validate before calling

let app = druid_shell::Application::try_global();
if app.is_none() {
    // no Application::new() yet, or run() has returned
}

Type guard

fn app_is_active() -> bool {
    druid_shell::Application::try_global().is_some()
}

Try / catch

// global() panics; prefer try_global:
match druid_shell::Application::try_global() {
    Some(app) => app,
    None => { eprintln!("Application::new() must be called first"); std::process::exit(1); }
}

Prevention

When it happens

Trigger: Calling Application::global() before ever calling Application::new(); calling it after run() has returned; calling it from a test or helper where no Application was initialized on the main thread (try_global also asserts main thread); constructing windows/headless contexts before app startup.

Common situations: Unit tests touching WindowBuilder or clipboard without app setup; background threads created before run(); utility binaries that build windows without an Application; calling global() in static initializers.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10). Data as JSON: /api/errors/d87ecde17e722b06. Report an issue: GitHub.

Appendix: source

Thrown at druid-shell/src/application.rs:98

    /// Get the current globally active `Application`.
    ///
    /// A globally active `Application` exists
    /// after [`new`] is called and until [`run`] returns.
    ///
    /// # Panics
    ///
    /// Panics if there is no globally active `Application`.
    /// For a non-panicking function use [`try_global`].
    ///
    /// This function will also panic if called from a non-main thread.
    ///
    /// [`new`]: #method.new
    /// [`run`]: #method.run
    /// [`try_global`]: #method.try_global
    #[inline]
    pub fn global() -> Application {
        // Main thread assertion takes place in try_global()
        Application::try_global().expect("There is no globally active Application")
    }

    /// Get the current globally active `Application`.
    ///
    /// A globally active `Application` exists
    /// after [`new`] is called and until [`run`] returns.
    ///
    /// # Panics
    ///
    /// Panics if called from a non-main thread.
    ///
    /// [`new`]: #method.new
    /// [`run`]: #method.run
    pub fn try_global() -> Option<Application> {
        util::assert_main_thread_or_main_unclaimed();
        GLOBAL_APP.with(|global_app| global_app.borrow().clone())
    }

View on GitHub (pinned to 0f8b1195e4)