slint-ui/slint · error

Cannot create placeholder

Error message

Cannot create placeholder: {err}

What it means

RemoteViewerWindow::new_with_existing_window failed while swap_to_placeholder tried to rebuild the placeholder UI on the existing window (used to show compile errors, pairing info, or 'component not found'). Creating a fresh placeholder window from the existing slint window failed, so the viewer cannot even display its fallback screen; the error is wrapped in anyhow and propagated as unrecoverable.

Solutions

  1. Verify the underlying window (placeholder.window()) is still valid before swapping; if the window is gone, exit the run loop instead of swapping.
  2. Update the viewer/editor to matching slint versions so the placeholder UI compiles and instantiates.
  3. Retry the connection flow from scratch so a fresh window and placeholder are created.
  4. Inspect the inner error from new_with_existing_window for the concrete instantiation failure cause.
Defensive patterns

Strategy: try-catch

Try / catch

match swap_to_placeholder(placeholder, user_instance, chrome, &message, RemoteViewerState::PreviewError) {
    Ok(()) => {},
    Err(e) if e.to_string().starts_with("Cannot create placeholder") => {
        // window is gone: exit the run loop instead of continuing
        tracing::error!("{e:#}");
        return; // or break out of the connection loop
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: swap_to_placeholder is invoked by run_async or build_and_show (on CompilationError/ComponentNotFound) and RemoteViewerWindow::new_with_existing_window(placeholder.window()) returns Err — the window handle is invalid/closed or the placeholder component cannot be instantiated into it.

Common situations: Device window was closed while an error message was being displayed; the placeholder .slint UI fails to instantiate on this backend; racing teardown during editor disconnect.

Related errors


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

Appendix: source

Thrown at tools/viewer/remote.rs:454

        window.set_address(SharedString::from(self.address.as_str()));
        window.set_name(SharedString::from(self.name.as_str()));
        window.set_slint_version(SharedString::from(SLINT_VERSION));
        window.set_build_info(build_info());
        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"))]

View on GitHub (pinned to bb937076de)