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
- Verify the decoded path exists on disk; if not, fetch dependencies (cargo fetch / npm install) so sources exist
- Check the authority's path_translation mapping matches the container's layout
- Reload the LSP workspace if the file was recently created or moved (stale index)
- 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
- Ensure dependency sources are fetched (cargo fetch, npm install) before navigating into them
- Keep host and container checkouts in sync with the authority's path_translation mapping
- Reload the LSP workspace after files are created/moved to avoid stale definition targets
- Stat the decoded path before opening and offer a fetch prompt when missing
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
- URI is not a file path
- No file path associated with buffer
- URI is not a file path (container-side decode failed)
- Buffer not found
- active window present
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)