astrid-runtime/astrid · error

Capsule has no cdylib target; refusing to guess a WASM…

Error message

Capsule has no cdylib target; refusing to guess a WASM artifact

What it means

Sentinel arm of resolve_wasm_output_name_from_targets: after filtering the package's cargo targets for cdylib kind, the list is empty, so there is no WASM artifact to package. The builder refuses to fall back to guessing a same-named binary target because a bin target produces a native executable, not the required .wasm. Fires for crates declared without crate-type = ["cdylib"].

Solutions

  1. Add `[lib] crate-type = ["cdylib"]` to Cargo.toml
  2. Check for a typo in the crate-type list
  3. Restructure so the WASM-producing crate is the one being built
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/astrid-build/src/rust.rs:168 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/36330c26a0eb8e2a. Report an issue: GitHub.

Appendix: source

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

/// cdylib target cannot produce the artifact this builder packages, so it is
/// rejected rather than guessing a same-named binary.
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())
}

View on GitHub (pinned to affd8760f4)