sinelaw/fresh · error

could not open : file not found

Error message

could not open {}: file not found

What it means

Final fallback of open_lsp_uri_target: the URI decoded to a host path but the file is neither reachable on the host filesystem nor fetchable from the container, so no buffer can be opened and this 'file not found' error is returned with the decoded path in the message.

Solutions

  1. Verify the decoded path exists on disk; if not, fetch dependencies (cargo fetch / npm install) so sources exist
  2. Check the authority's path_translation mapping matches the container's layout
  3. Reload the LSP workspace if the file was recently created or moved (stale index)
  4. Sync the file into the container/host so both sides see it

Example fix

// before
let buffer_id = self.open_lsp_uri_target(&uri)?;
// after
match self.open_lsp_uri_target(&uri) {
    Ok(id) => Ok(id),
    Err(e) if e.to_string().contains("file not found") => {
        log::warn!("definition target missing on disk; prompting fetch");
        self.prompt_fetch_missing_source(&uri)
    }
    Err(e) => Err(e),
}
Defensive patterns

Strategy: fallback

Validate before calling

let host = uri.to_host_path(translation.as_ref());
if let Some(p) = &host && !p.exists() && translation.is_none() {
    // surface 'file not found' to the user instead of erroring hard
}

Type guard

fn openable_on_host(uri: &LspUri, t: Option<&PathTranslation>) -> bool {
    uri.to_host_path(t).map(|p| p.exists()).unwrap_or(false)
}

Try / catch

match self.open_lsp_uri_target(&uri) {
    Err(e) if e.to_string().contains("file not found") => {
        self.show_message("Definition source not on disk — fetch dependencies or sync the file.");
    }
    other => other?,
}

Prevention

When it happens

Trigger: goto-definition targets a path that does not exist on the host (and no container translation applies), e.g. the symbol lives in a dependency's source that isn't checked out, or the workspace mounted in the container differs from the host checkout.

Common situations: Jumping to definition into a crate/dependency whose source isn't downloaded (no cargo registry sources, node_modules absent); stale LSP index pointing at deleted files; container path vs host path mismatch.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/451c0ed223746b28. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/src/app/file_open_orchestrators.rs:719

        // skip straight to the error case.
        if translation.is_some() {
            // The container-side path is the URI's raw path. Calling
            // `to_host_path` with `None` returns the wire-side path
            // verbatim (no translation applied) — exactly what we
            // need for `cat <path>` inside the container.
            let container_path = uri.to_host_path(None).ok_or_else(|| {
                anyhow::anyhow!("URI is not a file path (container-side decode failed)")
            })?;
            let buffer_id = self.fetch_and_open_container_file(container_path, uri.clone())?;
            // Match `open_file`'s focus behaviour so the cursor
            // assertion in callers (goto-def's `MoveCursor` event)
            // applies to the right buffer.
            self.set_active_buffer(buffer_id);
            return Ok(buffer_id);
        }

        // Case 3: nothing we can open.
        Err(anyhow::anyhow!(
            "could not open {}: file not found",
            host_path.display()
        ))
    }

    /// Run `cat <container_path>` through the active authority's
    /// process spawner and open the result as a read-only buffer
    /// tagged with the wire URI. Helper for [`Self::open_lsp_uri_target`].
    ///
    /// On `cat` exit-code 0 the bytes become the buffer's contents.
    /// On any error (no tokio runtime, spawner failure, non-zero
    /// exit) we return `Err` with a message that includes the
    /// container path and stderr's first line — enough for the
    /// caller's status-line surface.
    fn fetch_and_open_container_file(
        &mut self,
        container_path: std::path::PathBuf,
        uri: crate::app::types::LspUri,

View on GitHub (pinned to 67894ca546)