astrid-runtime/astrid · error
canonical Astrid workspace requires the kernel workspace…
Error message
canonical Astrid workspace requires the kernel workspace branch service
What it means
Thrown when assembling the canonical Astrid workspace: the kernel's `workspace_branches` service is `None` at the point the builder calls `with_workspace_branches`. The workspace branch service manages per-workspace branch state, which the canonical workspace requires, so startup aborts instead of creating a workspace without branch tracking.
Solutions
- Initialize and set the workspace branch service on the kernel before starting the canonical workspace
- Update kernel construction to call the workspace-branches builder method (likely newly required after a version change)
- Audit all kernel instantiation sites (including tests) so none skip workspace branch setup
Example fix
// before
let kernel = AstridKernel::builder()
.with_principal_store(store)
.build(); // workspace_branches left unset
// after
let kernel = AstridKernel::builder()
.with_principal_store(store)
.with_workspace_branches(branch_service)
.build(); Defensive patterns
Strategy: validation
Validate before calling
if kernel.workspace_branches().is_none() {
return Err(anyhow!("workspace branch service required for canonical workspace"));
} Type guard
fn has_workspace_branches(kernel: &AstridKernel) -> bool {
kernel.workspace_branches().is_some()
} Prevention
- Keep a single kernel-construction helper that sets every required service
- After kernel upgrades, re-check builder requirements against the new version's docs
- Cover kernel startup in an integration test that fails fast on missing wiring
When it happens
Trigger: Starting the native capsule runtime / canonical Astrid workspace while `self.workspace_branches` was never populated (lib.rs:1947, the `with_workspace_branches(...)` call in the builder chain).
Common situations: Kernel instances built without the workspace-branch initialization step; partial test fixtures that stub other services but omit workspace branches; upgrades where new required builder wiring (workspace branches) was not added to existing kernel construction code.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- native capsule runtime requires the authoritative principal…
- duplicate corpus label
- Failed to resolve ASTRID_HOME for handshake
- gateway is not wired to a live audit log; historical-query…
- gateway is not wired to a live event bus; agent approval…
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/666416ad988232b7.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/lib.rs:1947
// Durable home VFS authority is threaded separately through the
// UID-bound principal store. Do not pass a native PrincipalHome
// path into the steady-state capsule context.
None,
kv,
Arc::clone(&self.event_bus),
capsule_listener,
)
.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.View on GitHub (pinned to affd8760f4)