astrid-runtime/astrid · error

capsule {operation} '{}' is outside the explicit workspace p

Error message

capsule {operation} '{}' is outside the explicit workspace portal and has no durable registry authority

What it means

capture_bound_materialization first tries to bind the capsule to a durable registry publication (published_capsule_snapshot + repair) and then falls back to verifying the directory's installed authority. If neither applies — the registry verification fails AND a durable principal store exists but the target directory lies outside the explicit workspace state dir — the kernel refuses the operation: the capsule would run from an arbitrary path with no durable authority backing it, bypassing the workspace portal.

Source

Thrown at crates/astrid-kernel/src/capsule_materialization.rs:141

        if let Some(snapshot) = snapshot {
            let runtime_dir = self.published_cache_target(principal, manifest, &snapshot)?;
            let bound_manifest = self.repair_published_materialization(
                &runtime_dir,
                principal,
                manifest,
                &snapshot,
            )?;
            return Ok(Some(BoundMaterialization {
                snapshot,
                runtime_dir,
                manifest: bound_manifest,
            }));
        }
        if !self.verify_registry_materialization(dir, principal, manifest)? {
            if self.principal_store.is_some()
                && !dir.starts_with(self.workspace_selection.state_dir())
            {
                anyhow::bail!(
                    "capsule {operation} '{}' is outside the explicit workspace portal and \
                     has no durable registry authority",
                    manifest.package.name
                );
            }
            self.verify_installed_authority_for_runtime(dir, manifest).map_err(|error| {
                anyhow::anyhow!(
                    "capsule {operation} '{}' exceeds or cannot prove its installed authority: {error:#}",
                    manifest.package.name
                )
            })?;
        }
        Ok(None)
    }

    /// Repair a stale or missing cache generation from one exact snapshot.
    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
    pub(crate) fn ensure_published_materialization(

View on GitHub (pinned to affd8760f4)

Solutions

  1. Load the capsule from inside the explicit workspace portal (a path under workspace_selection.state_dir()) or install/publish it into the durable registry so verify_registry_materialization succeeds.
  2. Publish the capsule (register its snapshot and authority with the principal store) before attempting load_capsule/prepare_runtime_replacement on that path.
  3. Verify the workspace state_dir configuration matches where the capsule is actually materialized; a path-prefix mismatch alone triggers this bail.
  4. If a locally built capsule must run, route it through the workspace portal directory (copy/materialize it under state_dir) rather than passing its build path directly.

Example fix

// before: loading a capsule from an arbitrary path
let manifest = kernel.load_capsule(Path::new("/tmp/build/my-capsule"), &principal)?;

// after: load from inside the workspace portal state dir
let portal_dir = kernel.workspace_selection.state_dir().join("my-capsule");
let manifest = kernel.load_capsule(&portal_dir, &principal)?;
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the capsule lives in the workspace portal before loading
let state_dir = kernel.workspace_selection.state_dir();
let dir = std::fs::canonicalize(&dir)?;
let state_dir = std::fs::canonicalize(state_dir)?;
if !dir.starts_with(state_dir) {
    anyhow::bail!("capsule must be published or placed under the workspace state dir");
}

Type guard

fn inside_workspace(dir: &Path, state_dir: &Path) -> bool {
    match (std::fs::canonicalize(dir), std::fs::canonicalize(state_dir)) {
        (Ok(d), Ok(s)) => d.starts_with(s),
        _ => false,
    }
}

Try / catch

match kernel.load_capsule(&dir, &principal) {
    Err(e) if e.to_string().contains("outside the explicit workspace portal") => {
        publish_to_registry(&manifest)?; // or move capsule under state_dir
        kernel.load_capsule(&dir, &principal)
    }
    other => other,
}

Prevention

When it happens

Trigger: load_capsule or prepare_runtime_replacement is called with a `dir` such that published_capsule_snapshot finds no publication, verify_registry_materialization returns false, self.principal_store is Some, and dir does not start with self.workspace_selection.state_dir() — e.g. loading a capsule from /tmp/my-capsule or another project folder while a durable registry is configured.

Common situations: A developer points the loader at a local checkout/build-output directory instead of an installed or workspace-portal capsule; the workspace state dir is misconfigured (different path than where capsules were installed); a capsule was installed before the durable principal store was enabled and now lives outside the portal; CI copies capsule directories to scratch paths outside the workspace.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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