astrid-runtime/astrid · error

Capsule has cdylib targets; refusing to choose an ambiguous…

Error message

Capsule has {} cdylib targets; refusing to choose an ambiguous WASM artifact

What it means

Ambiguity guard in resolve_wasm_output_name_from_targets: the package declares more than one cdylib target, so the builder cannot decide which compiled .wasm to package into the single-component capsule. It fails loudly instead of silently choosing one. Triggered by multi-cdylib Cargo.toml layouts (e.g. a crate exposing several WASM entrypoints).

Solutions

  1. Keep exactly one cdylib target in Cargo.toml
  2. Move extra cdylibs into separate crates or non-cdylib target kinds
  3. Specify explicitly which target the capsule should package if tooling supports it
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/astrid-build/src/rust.rs:170 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at crates/astrid-build/src/rust.rs:170

fn resolve_wasm_output_name(package: &cargo_metadata::Package) -> Result<String> {
    resolve_wasm_output_name_from_targets(
        package
            .targets
            .iter()
            .filter(|target| target.is_cdylib())
            .map(|target| target.name.clone()),
    )
}

fn resolve_wasm_output_name_from_targets<I>(output_names: I) -> Result<String>
where
    I: IntoIterator<Item = String>,
{
    let output_names: Vec<String> = output_names.into_iter().collect();
    match output_names.as_slice() {
        [] => bail!("Capsule has no cdylib target; refusing to guess a WASM artifact"),
        [output_name] => validate_wasm_output_name(output_name),
        _ => bail!(
            "Capsule has {} cdylib targets; refusing to choose an ambiguous WASM artifact",
            output_names.len()
        ),
    }
}

fn validate_wasm_output_name(output_name: &str) -> Result<String> {
    let path = Path::new(output_name);
    let is_single_normal_component =
        output_name != "." && output_name != ".." && path.file_name() == Some(path.as_os_str());
    if !is_single_normal_component {
        bail!("Unsafe WASM artifact name: {output_name}");
    }
    Ok(output_name.to_owned())
}

/// Compile the capsule in release mode using whatever target Cargo resolves
/// from its complete configuration hierarchy.

View on GitHub (pinned to affd8760f4)