astrid-runtime/astrid · error · GatewayError::Internal

resolve selected workspace: {e}

Error message

resolve selected workspace: {e}

What it means

load_env_schema_from_home_in_workspace resolves the selected workspace root through workspace_layout.resolve and wraps any resolution failure as an Internal error. The workspace root was supplied by the caller, but the layout layer could not turn it into a valid workspace (bad path, missing markers, IO problems).

Source

Thrown at crates/astrid-gateway/src/routes/env.rs:380

) -> GatewayResult<HashMap<String, EnvFieldSchema>> {
    // Principal installs override workspace capsules, matching runtime
    // discovery. The manifest is read only after `ensure_capsule_visible` has
    // confirmed that the same principal is allowed to see the capsule.
    let principal_manifest = home
        .principal_home(principal)
        .capsules_dir()
        .join(capsule_id)
        .join("Capsule.toml");
    if principal_manifest.exists() {
        return parse_env_schema(&principal_manifest);
    }

    let Some(workspace_root) = workspace_root else {
        return Err(GatewayError::NotFound);
    };
    let workspace = workspace_layout
        .resolve(workspace_root)
        .map_err(|e| GatewayError::Internal(anyhow::anyhow!("resolve selected workspace: {e}")))?;
    let manifest_relative = FsPath::new("capsules")
        .join(capsule_id)
        .join("Capsule.toml");
    let workspace_manifest = workspace.resolve_file(&manifest_relative).map_err(|e| {
        GatewayError::Internal(anyhow::anyhow!("resolve workspace capsule manifest: {e}"))
    })?;
    if !workspace_manifest.exists() {
        return Err(GatewayError::NotFound);
    }
    let schema = parse_env_schema(&workspace_manifest)?;
    workspace.resolve_file(&manifest_relative).map_err(|e| {
        GatewayError::Internal(anyhow::anyhow!(
            "workspace capsule manifest changed while it was being read: {e}"
        ))
    })?;
    Ok(schema)
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Verify the workspace root path exists and is a valid workspace directory, then retry
  2. Re-register or re-select the correct workspace so home config points at a live root
  3. Check filesystem permissions on the workspace path

Example fix

// before
let workspace = workspace_layout
    .resolve(workspace_root)
    .map_err(|e| GatewayError::Internal(anyhow::anyhow!("resolve selected workspace: {e}")))?;
// after
let workspace = workspace_layout.resolve(workspace_root).map_err(|e| {
    tracing::warn!(root = %workspace_root.display(), error = %e, "workspace resolve failed");
    GatewayError::NotFound
})?;
Defensive patterns

Strategy: validation

Validate before calling

let root = std::path::PathBuf::from(&workspace_root);
if !root.is_dir() {
    return Err(GatewayError::NotFound);
}

Type guard

fn is_valid_workspace_root(p: &FsPath) -> bool {
    p.is_dir() && p.join("capsules").is_dir()
}

Try / catch

match load_env_schema_from_home(state, &capsule_id).await {
    Ok(schema) => schema,
    Err(GatewayError::Internal(e)) if e.to_string().starts_with("resolve selected workspace") => {
        // workspace root is stale; ask the user to re-select a workspace
        workspace_selection_required()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling load_env_schema_from_home (directly or via the env-schema route/tests) with a workspace_root that workspace_layout.resolve cannot resolve — e.g. a path that doesn't exist, is not a directory, or lacks required workspace structure.

Common situations: Stale or deleted workspace root recorded in home config; workspace directory moved or renamed; permission problems on the workspace path; typo'd workspace id in the request.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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