astrid-runtime/astrid · error

native process storage mount broker unavailable

Error message

native process storage mount broker unavailable

What it means

Thrown when the native runtime builder cannot obtain the process storage mount broker: `self.process_storage_mount_broker.get().cloned()` returns `None`. The broker coordinates mounting process storage for capsules, and the native runtime treats it as mandatory, so assembly fails fast.

Solutions

  1. Initialize the process storage mount broker before starting the native runtime (the setter/OnceCell that populates `process_storage_mount_broker`)
  2. Ensure the standard kernel bootstrap sequence is used so the broker is installed in the right order
  3. If only launching capsules without process storage, use a runtime configuration that does not require the mount broker

Example fix

// before
let kernel = AstridKernel::builder().build();
kernel.start_native_capsule_runtime().await?; // broker never set
// after
kernel.init_process_storage_mount_broker(broker)?;
kernel.start_native_capsule_runtime().await?;
Defensive patterns

Strategy: validation

Validate before calling

if kernel.process_storage_mount_broker().is_none() {
    return Err(anyhow!("process storage mount broker must be initialized first"));
}

Type guard

fn has_mount_broker(kernel: &AstridKernel) -> bool {
    kernel.process_storage_mount_broker().is_some()
}

Prevention

When it happens

Trigger: Starting the native capsule runtime when the OnceCell `process_storage_mount_broker` was never initialized (lib.rs:1955, `with_process_storage_mount_broker(...)`).

Common situations: Kernel constructed without process-storage initialization (e.g. storage layer skipped in embedded/test setups); race or ordering bug where the broker is set only after runtime start; code paths that construct the kernel manually instead of through the standard bootstrap that installs the broker.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — 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/c88b95443e080227. Report an issue: GitHub.

Appendix: source

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

        .with_astrid_workspace()
        .with_principal_storage(
            self.principal_store.clone().ok_or_else(|| {
                anyhow::anyhow!(
                    "native capsule runtime requires the authoritative principal store"
                )
            })?,
            self.principal_directory.clone(),
        )
        .with_workspace_branches(self.workspace_branches.clone().ok_or_else(|| {
            anyhow::anyhow!(
                "canonical Astrid workspace requires the kernel workspace branch service"
            )
        })?)
        .with_process_storage_mount_broker(
            self.process_storage_mount_broker
                .get()
                .cloned()
                .ok_or_else(|| anyhow::anyhow!("native process storage mount broker unavailable"))?,
        )
        .with_registry(Arc::clone(&self.capsules))
        .with_session_token(Arc::clone(&self.session_token))
        .with_allowance_store(Arc::clone(&self.allowance_store))
        .with_identity_store(Arc::clone(&self.identity_store))
        .with_profile_cache(Arc::clone(&self.profile_cache))
        .with_overlay_registry(Arc::clone(&self.overlay_registry))
        // Thread the live group config so capsule invocation checks observe
        // runtime group mutations without requiring capsule reloads. Load-time
        // run-loop decisions take their own explicit snapshot.
        .with_live_group_config(Arc::clone(&self.groups))
        // Hand this capsule its operator-approved local-egress allowlist (if
        // any) so the SSRF airlock can exempt sanctioned loopback/private
        // endpoints for it. Absent entry = empty = no exemptions.
        .with_local_egress(
            self.local_egress
                .read()
                .unwrap_or_else(std::sync::PoisonError::into_inner)

View on GitHub (pinned to affd8760f4)