{"record":{"id":"3eb2a5f9212703f0","repo":"astrid-runtime/astrid","slug":"capsule-has-cdylib-targets-refusing-to-choose","errorCode":null,"errorMessage":"Capsule has {} cdylib targets; refusing to choose an ambiguous WASM artifact","messagePattern":"Capsule has (.+?) cdylib targets; refusing to choose an ambiguous WASM artifact","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-build/src/rust.rs","lineNumber":170,"sourceCode":"fn resolve_wasm_output_name(package: &cargo_metadata::Package) -> Result<String> {\n    resolve_wasm_output_name_from_targets(\n        package\n            .targets\n            .iter()\n            .filter(|target| target.is_cdylib())\n            .map(|target| target.name.clone()),\n    )\n}\n\nfn resolve_wasm_output_name_from_targets<I>(output_names: I) -> Result<String>\nwhere\n    I: IntoIterator<Item = String>,\n{\n    let output_names: Vec<String> = output_names.into_iter().collect();\n    match output_names.as_slice() {\n        [] => bail!(\"Capsule has no cdylib target; refusing to guess a WASM artifact\"),\n        [output_name] => validate_wasm_output_name(output_name),\n        _ => bail!(\n            \"Capsule has {} cdylib targets; refusing to choose an ambiguous WASM artifact\",\n            output_names.len()\n        ),\n    }\n}\n\nfn validate_wasm_output_name(output_name: &str) -> Result<String> {\n    let path = Path::new(output_name);\n    let is_single_normal_component =\n        output_name != \".\" && output_name != \"..\" && path.file_name() == Some(path.as_os_str());\n    if !is_single_normal_component {\n        bail!(\"Unsafe WASM artifact name: {output_name}\");\n    }\n    Ok(output_name.to_owned())\n}\n\n/// Compile the capsule in release mode using whatever target Cargo resolves\n/// from its complete configuration hierarchy.","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-build/src/rust.rs#L152-L188","documentation":"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).","triggerScenarios":"Thrown at crates/astrid-build/src/rust.rs:170 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Keep exactly one cdylib target in Cargo.toml","Move extra cdylibs into separate crates or non-cdylib target kinds","Specify explicitly which target the capsule should package if tooling supports it"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}