astrid-runtime/astrid · error

unsafe workspace selection: {error}

Error message

unsafe workspace selection: {error}

What it means

During kernel startup, `workspace_layout.resolve(&workspace_root)` rejected the workspace selection as unsafe (e.g. root/symlink/ownership problems per the layout rules). The kernel re-wraps the rejection with its original ErrorKind and the message prefix `unsafe workspace selection:` because it will only operate inside a safely-resolved project root.

Source

Thrown at crates/astrid-kernel/src/lib.rs:1065

            runtime_key,
            session_token,
            token_path,
            cli_socket_listener,
            singleton_lock,
            #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
            layout_origin,
        } = resources;
        #[cfg(not(unix))]
        let _ = token_path;

        home.clear_runtime_principal_scratch().map_err(|error| {
            std::io::Error::other(format!(
                "Failed to clear stale principal runtime scratch: {error}"
            ))
        })?;

        let workspace_selection = workspace_layout.resolve(&workspace_root).map_err(|error| {
            std::io::Error::new(error.kind(), format!("unsafe workspace selection: {error}"))
        })?;
        let workspace_root = workspace_selection.project_root().to_path_buf();

        let event_bus = Arc::new(EventBus::new());
        let capsules = Arc::new(RwLock::new(CapsuleRegistry::new()));

        // The canonical runtime has no native principal-home authority. Home
        // and workspace mounts are bound from the durable storage provider;
        // lifecycle compatibility callers receive an explicit `None` and
        // must not recreate a host `principal_home` tree.
        let home_root = None;

        // Bootstrap the capability store (persistent) over the injected KV.
        // Key rotation invalidates persisted tokens (fail-secure by design).
        let capabilities = Arc::new(
            CapabilityStore::with_kv_store(Arc::clone(&kv))
                .await
                .map_err(|e| {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Use the real, non-symlinked path as the workspace root (resolve the canonical path and cd there).
  2. Fix ownership/permissions so the workspace root belongs to the current user.
  3. Move the workspace to a location the layout rules permit.
  4. Read the inner `{error}` in the message — it names the specific layout rule that was violated.

Example fix

// before
let root = PathBuf::from("~/projects/link-to-app"); // symlink
// after
let root = std::fs::canonicalize("~/projects/link-to-app")?; // real path
let workspace = workspace_layout.resolve(&root)?;
Defensive patterns

Strategy: try-catch

Validate before calling

let root = std::fs::canonicalize(&workspace_root)?;
if !root.is_dir() {
    return Err("workspace root must be a real directory");
}
let selection = workspace_layout.resolve(&root)?;

Type guard

fn safe_workspace_root(p: &std::path::Path) -> std::io::Result<bool> {
    let real = std::fs::canonicalize(p)?;
    Ok(real.is_dir() && real == p)
}

Try / catch

match workspace_layout.resolve(&workspace_root) {
    Err(e) => return Err(std::io::Error::new(e.kind(), format!("unsafe workspace selection: {e}; use a real, non-symlinked, user-owned directory"))),
    Ok(sel) => sel,
};

Prevention

When it happens

Trigger: Starting the kernel with a workspace root that `workspace_layout.resolve` deems unsafe — symlinked or redirected workspace roots, disallowed locations, or ownership/permission mismatches on the path.

Common situations: Running the tool inside a symlinked project directory (or a symlinked HOME chain); a workspace mounted from another user's directory; CI checkouts with unusual symlink structures; containers mapping volumes with mismatched uids.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/142a51edddf82a46. Report an issue: GitHub.