astrid-runtime/astrid · error
failed to resolve workspace root {}: {error}
Error message
failed to resolve workspace root {}: {error} What it means
WorkspaceSelection::resolve canonicalizes the supplied project_root to obtain the true absolute workspace root, and wraps any std::fs::canonicalize failure (not-found, permission denied, symlink loop, I/O error) in an io::Error preserving the original kind while adding context: the unresolved path and the underlying OS error. The library cannot establish a trusted workspace root without a canonical path.
Source
Thrown at crates/astrid-core/src/workspace_security.rs:26
use super::WorkspaceLayout;
/// A checked project workspace selection.
///
/// The project root is canonical and the selected state directory is either
/// absent or a real directory directly beneath that root. Symlinks, junctions,
/// and other redirects are rejected by requiring an existing directory to
/// canonicalize to the exact direct-child path selected here.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkspaceSelection {
project_root: PathBuf,
state_dir: PathBuf,
layout: WorkspaceLayout,
}
impl WorkspaceSelection {
pub(super) fn resolve(project_root: &Path, layout: WorkspaceLayout) -> io::Result<Self> {
let project_root = std::fs::canonicalize(project_root).map_err(|error| {
io::Error::new(
error.kind(),
format!(
"failed to resolve workspace root {}: {error}",
project_root.display()
),
)
})?;
crate::platform_fs::verify_no_redirects(&project_root)?;
if !std::fs::metadata(&project_root)?.is_dir() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!(
"workspace root is not a directory: {}",
project_root.display()
),
));
}
View on GitHub (pinned to affd8760f4)
Solutions
- Create the project root directory if it does not exist (std::fs::create_dir_all) before resolving the workspace.
- Fix the configured project root path (typo, wrong cwd, relative path resolved from an unexpected working directory).
- Repair or remove broken symlinks along the path.
- Check permissions on every path component so the process can traverse to the root.
- Investigate the wrapped OS error in the message (e.g. ENOENT vs EACCES vs ELOOP) to target the exact cause.
Example fix
// before
let sel = WorkspaceSelection::resolve(Path::new("/opt/missing-project"), layout)?;
// after
let root = Path::new("/opt/my-project");
std::fs::create_dir_all(root)?;
let sel = WorkspaceSelection::resolve(root, layout)?; Defensive patterns
Strategy: validation
Validate before calling
fn root_ready(p: &Path) -> std::io::Result<()> {
let meta = std::fs::metadata(p).map_err(|e| e)?;
if !meta.is_dir() { return Err(io::Error::new(io::ErrorKind::InvalidInput, "not a dir")); }
Ok(())
} Try / catch
match WorkspaceSelection::resolve(root, layout) {
Err(e) => { log::error!("cannot resolve workspace root: {e}"); return Err(e); }
Ok(sel) => sel,
} Prevention
- create_dir_all the project root before resolving
- Resolve relative roots against an explicit, fixed current directory
- Avoid symlinked project roots or canonicalize early and reuse the result
- Check the wrapped OS error kind (ENOENT/EACCES/ELOOP) to diagnose quickly
When it happens
Trigger: Calling WorkspaceSelection::resolve (directly or via ensure_state_dir / resolve_directory / resolve_file / verify) with a project_root that does not exist, is unreadable due to permissions, sits behind a broken symlink, or contains a symlink loop.
Common situations: Typo in the configured project root; running before project initialization created the directory; the workspace was deleted or moved while the process held a stale path; NFS/network mounts returning EIO; restrictive file permissions after a container user switch.
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
- resolve workspace capsule manifest: {e}
- workspace root is not a directory: {}
- workspace capsule directory is redirected: {}
- read {}: {e}
- inspect legacy revocation file: {error}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/9a2fc6ba117fd672.
Report an issue: GitHub.