slint-ui/slint · error · std::io::Error

Failed to convert path to URL

Error message

Failed to convert path to URL

What it means

`get_path_from_cache` converts a filesystem path to a `file://` URL with `Url::from_file_path` before consulting the source cache. Only absolute paths can be converted; relative paths (or paths with a non-root base like Windows drive-less paths) make the conversion fail, reported as `NotFound`.

Solutions

  1. Canonicalize the path to absolute before calling `get_path_from_cache`: `std::fs::canonicalize(path)`
  2. If the file may not exist on disk, build the absolute path from a known base directory (`base.join(rel)`) then convert
  3. Confirm the path the loader receives is absolute; if the origin is an import string, resolve it against the importing file's directory first

Example fix

// before
let r = get_path_from_cache(Path::new("ui/main.slint"))?;
// after
let abs = std::fs::canonicalize("ui/main.slint")?;
let r = get_path_from_cache(&abs)?;
Defensive patterns

Strategy: validation

Validate before calling

if !path.is_absolute() {
    let path = std::fs::canonicalize(path).map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, e))?;
}
let url = Url::from_file_path(path).map_err(|()| std::io::Error::new(std::io::ErrorKind::NotFound, "Failed to convert path to URL"))?;

Type guard

fn to_file_url(p: &std::path::Path) -> Option<Url> {
    if p.is_absolute() { Url::from_file_path(p).ok() } else { None }
}

Try / catch

match get_path_from_cache(&path) {
    Ok(result) => result,
    Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
        let abs = std::fs::canonicalize(&path)?;
        get_path_from_cache(&abs)
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: `get_path_from_cache(&path)` is called with a relative `Path` (e.g. derived from a compiler import string or a user-supplied relative path), so `Url::from_file_path` returns `Err(())`.

Common situations: A relative import path propagated straight from the .slint source; running the tool with a CWD different from what the caller assumed; paths built via `PathBuf::from("relative/file.slint")` without canonicalization.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at tools/editor/preview.rs:2041

/// Otherwise the file is indeed missing.
///
/// In any way, register it as a dependency
fn get_url_from_cache(url: &Url) -> std::io::Result<(SourceFileVersion, String)> {
    PREVIEW_STATE.with_borrow_mut(|preview_state| {
        preview_state.dependencies.insert(url.to_owned());

        preview_state.source_code.get(url).map(|r| (r.version, r.code.clone())).ok_or(
            std::io::Error::new(
                std::io::ErrorKind::NotFound,
                "File not registered in Live-Preview!",
            ),
        )
    })
}

fn get_path_from_cache(path: &Path) -> std::io::Result<(SourceFileVersion, String)> {
    let url = Url::from_file_path(path).map_err(|()| {
        std::io::Error::new(std::io::ErrorKind::NotFound, "Failed to convert path to URL")
    })?;
    get_url_from_cache(&url)
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum LoadBehavior {
    /// We reload the preview, most likely because a file has changed
    Reload,
    /// Load the preview and make the window visible if it wasn't already.
    LoadWithoutLiveData,
    /// We show the preview because the user asked for it. The UI should become visible and focused if it wasn't already
    BringWindowToFront,
}

pub fn reload_preview() {
    let pc = PREVIEW_STATE
        .with_borrow(|preview_state| preview_state.current_previewed_component.clone());

View on GitHub (pinned to 3a7e700487)