slint-ui/slint · error

Cannot show placeholder

Error message

Cannot show placeholder: {err}

What it means

fresh.show() failed in swap_to_placeholder after the placeholder window was successfully created and populated with the chrome (address, name, licenses) and status message. The runtime could not present the placeholder screen on the existing window, so the fallback UI cannot be displayed and the error propagates as unrecoverable.

Solutions

  1. Retry by restarting the remote viewer flow so the event loop and window are re-created.
  2. Ensure the slint platform/event loop is initialized and running before swap_to_placeholder is called.
  3. Guard against swapping during window teardown: check that the connection/window is still live first.
  4. Inspect the inner show() error to identify the platform-backend cause and fix the window setup.
Defensive patterns

Strategy: try-catch

Try / catch

match fresh.show() {
    Ok(()) => { *placeholder = fresh; *user_instance = None; },
    Err(err) => {
        tracing::error!("Cannot show placeholder: {err}");
        // surface a connection error to the caller; do not continue with a half-swapped state
        return Err(anyhow::anyhow!(err.to_string()));
    }
}

Prevention

When it happens

Trigger: swap_to_placeholder (called from run_async or build_and_show) succeeds in creating `fresh` but fresh.show() returns Err — the platform backend refuses to show the window (event loop dead, window in teardown, renderer failure).

Common situations: Window/backend teardown races the placeholder swap when the editor disconnects; embedded platform cannot show a window at this point (e.g. display not ready); slint platform initialization failure on the device.

Related errors


AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16). Data as JSON: /api/errors/9e9b67185593f3ab. Report an issue: GitHub.

Appendix: source

Thrown at tools/viewer/remote.rs:458

        window.set_third_party_licenses(self.licenses.clone());
        window.set_pairing_disabled(self.pairing_disabled);
    }
}

/// Reinstall a fresh placeholder onto the existing window and drop the user instance.
fn swap_to_placeholder(
    placeholder: &mut RemoteViewerWindow,
    user_instance: &mut Option<slint_interpreter::ComponentInstance>,
    chrome: &Chrome,
    message: &str,
    state: RemoteViewerState,
) -> anyhow::Result<()> {
    let fresh = RemoteViewerWindow::new_with_existing_window(placeholder.window())
        .map_err(|err| anyhow::anyhow!("Cannot create placeholder: {err}"))?;
    chrome.apply(&fresh);
    fresh.set_message(SharedString::from(message));
    fresh.set_state(state);
    fresh.show().map_err(|err| anyhow::anyhow!("Cannot show placeholder: {err}"))?;
    *placeholder = fresh;
    *user_instance = None;
    Ok(())
}

/// Platform-specific override for the friendly device name. Returns `None` on platforms
/// where the default chain in `Connection` (pretty hostname → hostname, then Bonjour on
/// Apple) is already best.
fn device_name_override() -> Option<String> {
    #[cfg(target_os = "android")]
    {
        ANDROID_DEVICE_NAME.lock().unwrap_or_else(|e| e.into_inner()).clone()
    }
    #[cfg(not(target_os = "android"))]
    {
        None
    }
}

View on GitHub (pinned to bb937076de)