sinelaw/fresh · error

missing path in response

Error message

missing path in response

What it means

canonicalize sent a realpath request to the remote agent and the response JSON had no string under the "path" key. The adapter requires the canonical path field, so an absent/malformed path is raised as InvalidData instead of returning an empty PathBuf.

Solutions

  1. Verify the remote path exists before calling canonicalize (e.g. stat/metadata first).
  2. Check agent/editor protocol compatibility; ensure realpath replies with {"path": "..."}.
  3. Log the raw realpath response and treat missing-path as a not-found condition for the caller.

Example fix

// before
let canon = remote_fs.canonicalize(&path)?;
// after
if !remote_fs.exists(&path) {
    eprintln!("skipping canonicalize for missing path {path}");
    return Ok(path.into());
}
let canon = remote_fs.canonicalize(&path)?;
Defensive patterns

Strategy: validation

Validate before calling

if !remote_fs.exists(&path) { return Err(format!("cannot canonicalize missing path: {}", path.display()).into()); }

Type guard

fn valid_realpath_response(v: &serde_json::Value) -> bool { v.get("path").and_then(|p| p.as_str()).map(|s| !s.is_empty()).unwrap_or(false) }

Try / catch

let canon = remote_fs.canonicalize(&path).unwrap_or_else(|_| path.to_path_buf());

Prevention

When it happens

Trigger: A realpath response missing "path" — agent error payload, protocol mismatch, or the remote failing to resolve the given path while still returning a 200-style result object.

Common situations: Requesting canonicalize on a nonexistent remote path, agent version with renamed response fields, or a custom remote agent that returns errors in a different schema.

Related errors


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

Appendix: source

Thrown at crates/fresh-editor/src/services/remote/filesystem.rs:539

        let params = serde_json::json!({
            "path": path.to_string_lossy(),
            "parents": true
        });
        self.channel
            .request_blocking("mkdir", params)
            .map_err(Self::to_io_error)?;
        Ok(())
    }

    fn canonicalize(&self, path: &Path) -> io::Result<PathBuf> {
        let params = serde_json::json!({"path": path.to_string_lossy()});
        let result = self
            .channel
            .request_blocking("realpath", params)
            .map_err(Self::to_io_error)?;

        let canonical = result.get("path").and_then(|v| v.as_str()).ok_or_else(|| {
            io::Error::new(io::ErrorKind::InvalidData, "missing path in response")
        })?;

        Ok(PathBuf::from(canonical))
    }

    fn current_uid(&self) -> u32 {
        // We don't know the remote user's UID easily, return 0
        // This is used for ownership checks which we skip for remote
        0
    }

    fn remote_connection_info(&self) -> Option<&str> {
        Some(&self.connection_string)
    }

    fn is_remote_connected(&self) -> bool {
        self.channel.is_connected()
    }

View on GitHub (pinned to 67894ca546)