{"record":{"id":"95dc79f958f06a14","repo":"sinelaw/fresh","slug":"uri-is-not-a-file-path-container-side-decode-failed","errorCode":null,"errorMessage":"URI is not a file path (container-side decode failed)","messagePattern":"URI is not a file path \\(container-side decode failed\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/app/file_open_orchestrators.rs","lineNumber":708,"sourceCode":"        // `open_file` focuses, which is what callers (goto-def,\n        // workspace edits) expect — they want the cursor to land in\n        // the destination buffer afterward.\n        if self.authority().filesystem.exists(&host_path) {\n            return self.open_file(&host_path);\n        }\n\n        // Case 2: container-only fetch. Only meaningful when the\n        // active authority can route a `cat` through to the\n        // container — `path_translation` being set is the proxy for\n        // \"this is a container authority\". Local + SSH authorities\n        // skip straight to the error case.\n        if translation.is_some() {\n            // The container-side path is the URI's raw path. Calling\n            // `to_host_path` with `None` returns the wire-side path\n            // verbatim (no translation applied) — exactly what we\n            // need for `cat <path>` inside the container.\n            let container_path = uri.to_host_path(None).ok_or_else(|| {\n                anyhow::anyhow!(\"URI is not a file path (container-side decode failed)\")\n            })?;\n            let buffer_id = self.fetch_and_open_container_file(container_path, uri.clone())?;\n            // Match `open_file`'s focus behaviour so the cursor\n            // assertion in callers (goto-def's `MoveCursor` event)\n            // applies to the right buffer.\n            self.set_active_buffer(buffer_id);\n            return Ok(buffer_id);\n        }\n\n        // Case 3: nothing we can open.\n        Err(anyhow::anyhow!(\n            \"could not open {}: file not found\",\n            host_path.display()\n        ))\n    }\n\n    /// Run `cat <container_path>` through the active authority's\n    /// process spawner and open the result as a read-only buffer","sourceCodeStart":690,"sourceCodeEnd":726,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/app/file_open_orchestrators.rs#L690-L726","documentation":"In open_lsp_uri_target's container branch (a translation/authority is active), the code decodes the URI's raw path verbatim to run `cat <path>` inside the container. If uri.to_host_path(None) returns None — the URI has no decodable file path — this error is thrown before any container command runs.","triggerScenarios":"goto-definition returns a non-file:// or malformed URI while the editor is attached to a devcontainer/remote authority, so the container-side decode of the URI path fails.","commonSituations":"Remote development against a language server that reports definitions with virtual or custom URI schemes; a corrupt URI produced by a buggy server over the wire.","solutions":["Log and inspect the incoming LspUri; confirm it is a file:// URI with a non-empty path","Handle virtual-document schemes separately instead of treating them as container paths","Check the LSP server version/config for options that emit plain file paths","Fall back to Case 1 (host path) semantics or surface a friendly message when the URI is not a file"],"exampleFix":"// before\nlet container_path = uri.to_host_path(None).ok_or_else(|| {\n    anyhow::anyhow!(\"URI is not a file path (container-side decode failed)\")\n})?;\n// after\nlet Some(container_path) = uri.to_host_path(None) else {\n    log::warn!(\"skipping non-file LSP URI: {}\", uri.as_str());\n    return Ok(self.active_buffer_id());\n};","handlingStrategy":"validation","validationCode":"if translation.is_some() && uri.to_host_path(None).is_none() {\n    // skip container fetch, show message instead\n}","typeGuard":"fn container_path_of(uri: &LspUri) -> Option<std::path::PathBuf> {\n    uri.to_host_path(None)\n}","tryCatchPattern":"match self.open_lsp_uri_target(&uri) {\n    Err(e) if e.to_string().contains(\"container-side decode failed\") => {\n        log::warn!(\"cannot fetch non-file URI from container: {}\", uri.as_str());\n    }\n    other => other?,\n}","preventionTips":["Decode the URI path with to_host_path(None) before entering the container branch","Reject virtual-document schemes early in the goto-definition handler","Test container-mode goto-definition with servers known to emit non-file URIs","Keep container fetch behind a capability check so invalid URIs degrade gracefully"],"tags":["lsp","uri","devcontainer"],"backgroundTag":"invalid-url-format","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}