astrid-runtime/astrid · error
opaque capsule assets cannot be symlinks: {}
Error message
opaque capsule assets cannot be symlinks: {} What it means
In the FUSE storage provider's hidden service mode, run_launch computes the parent-challenge for the readiness handshake via storage_provider_service_ready_challenge and maps any error it returns into an anyhow error using the error's Display text ('{error}'). It indicates the launch handshake inputs (parent token, mount id, paths) failed challenge derivation, so the service cannot prove itself to the parent process.
Source
Thrown at crates/astrid-build/src/archiver.rs:50
if metadata.file_type().is_symlink() {
anyhow::bail!(
"opaque capsule asset directories cannot be symlinks: {}",
root.display()
);
}
if !metadata.is_dir() {
anyhow::bail!("opaque asset path must be a directory: {}", root.display());
}
let mut pending = vec![root];
while let Some(dir) = pending.pop() {
for entry in fs::read_dir(&dir)
.with_context(|| format!("Failed to read asset directory: {}", dir.display()))?
{
let entry = entry?;
let path = entry.path();
let file_type = entry.file_type()?;
if file_type.is_symlink() {
anyhow::bail!(
"opaque capsule assets cannot be symlinks: {}",
path.display()
);
}
if file_type.is_dir() {
pending.push(path);
} else if file_type.is_file() {
files.push(path);
}
}
}
}
files.sort();
Ok(files)
}
/// Packages a set of files and directories into a single `.capsule` (tar.gz) archive.
pub(crate) fn pack_capsule_archive(View on GitHub (pinned to affd8760f4)
Solutions
- Inspect the inner error text to see which challenge input failed, then fix the parent-side launch payload accordingly.
- Ensure launch.parent.token is a valid, non-empty token produced by storage_provider_service_ready_challenge's counterpart on the parent side.
- Verify control_path, resource_path and callback_path are absolute, valid paths and mount_id is a well-formed UUID.
Example fix
// before
let challenge = storage_provider_service_ready_challenge(
&launch.parent.token, /* token from hand-built launch JSON */ ...
).map_err(|error| anyhow::anyhow!(error))?;
// after
// construct the launch via the parent SDK so the token is derived from the same inputs
let launch = StorageProviderServiceLaunchV1::build(&lease, &parent)?;
let challenge = storage_provider_service_ready_challenge(
&launch.parent.token, ...
).map_err(|error| anyhow::anyhow!(error))?; Defensive patterns
Strategy: try-catch
Validate before calling
fn launch_inputs_ok(launch: &StorageProviderServiceLaunchV1) -> bool {
!launch.parent.token.is_empty()
&& launch.lease.mount_id.as_uuid() != uuid::Uuid::nil()
&& !launch.control_path.as_os_str().is_empty()
} Try / catch
match run_launch(launch).await {
Err(e) => { eprintln!("FUSE launch failed: {e:#}"); std::process::exit(1); },
Ok(()) => {},
} Prevention
- Construct launch payloads via the parent-side SDK helper
- Log the full error chain ({e:#}) to find the failing input
- Keep parent and provider versions in sync
When it happens
Trigger: run (FUSE service mode) receives a StorageProviderServiceLaunchV1 on stdin, passes validate_launch, then storage_provider_service_ready_challenge returns Err — e.g. malformed or empty parent token, or invalid path/UUID inputs — and run_launch propagates it verbatim.
Common situations: Parent process passed an empty or wrongly-encoded parent.token; control/resource/callback paths contain invalid characters or are empty; mount_id UUID serialization mismatch between parent and provider versions.
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
- FUSE control request exceeds the bounded frame size
- FUSE service control response exceeds the bounded frame size
- FUSE service status failed [{code}]: {message}
- detached FUSE service exceeded the startup response size
- detached FUSE service did not retain its control endpoint
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/3ac1ed37cbb828a9.
Report an issue: GitHub.