{"record":{"id":"2625a8e52db3e20e","repo":"astrid-runtime/astrid","slug":"capsule-toml-has-no-package-version","errorCode":null,"errorMessage":"Capsule.toml has no package.version","messagePattern":"Capsule\\.toml has no package\\.version","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-capsule-install/src/storage.rs","lineNumber":730,"sourceCode":"        }\n    }\n    Ok(())\n}\n\nfn manifest_identity(source_dir: &Path) -> anyhow::Result<(String, String)> {\n    let manifest = fs::read_to_string(source_dir.join(\"Capsule.toml\"))\n        .with_context(|| format!(\"read capsule manifest from {}\", source_dir.display()))?;\n    let value: toml::Value = toml::from_str(&manifest).context(\"parse capsule manifest\")?;\n    let id = value\n        .get(\"package\")\n        .and_then(|package| package.get(\"name\"))\n        .and_then(toml::Value::as_str)\n        .ok_or_else(|| anyhow::anyhow!(\"Capsule.toml has no package.name\"))?;\n    let version = value\n        .get(\"package\")\n        .and_then(|package| package.get(\"version\"))\n        .and_then(toml::Value::as_str)\n        .ok_or_else(|| anyhow::anyhow!(\"Capsule.toml has no package.version\"))?;\n    Ok((id.to_owned(), version.to_owned()))\n}\n\nfn authority_capsule_id(authority: &[u8]) -> anyhow::Result<String> {\n    let authority: InstalledAuthority =\n        serde_json::from_slice(authority).context(\"decode authority receipt for package id\")?;\n    if authority.capsule_id.is_empty() {\n        bail!(\"authority receipt has an empty capsule id\");\n    }\n    Ok(authority.capsule_id)\n}\n\n/// Build a deterministic gzip/tar package from a checked directory.\npub fn canonical_capsule_archive(source_dir: &Path) -> anyhow::Result<Vec<u8>> {\n    let mut entries = Vec::new();\n    collect_entries(source_dir, source_dir, &mut entries)?;\n    if !entries\n        .iter()","sourceCodeStart":712,"sourceCodeEnd":748,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-capsule-install/src/storage.rs#L712-L748","documentation":"manifest_identity also reads package.version from Capsule.toml to establish the capsule identity. When the [package] table exists but has no string version field, the library throws because a publishable capsule must be versioned.","triggerScenarios":"publish_directory_package parses Capsule.toml successfully and finds package.name, but value.get(\"package\").get(\"version\").as_str() is None — the version key is absent or is not a string (e.g. a float like 0.1).","commonSituations":"Newly initialized capsule projects where the developer added name but not version; version written unquoted as a TOML float (version = 1.0); manifests edited by tooling that strips version.","solutions":["Add a string version field under [package] in Capsule.toml (quote it so TOML keeps it a string) and republish.","If version was written as a number (version = 0.1), change it to a quoted string (version = \"0.1.0\").","Regenerate Capsule.toml with the current scaffolding tool to get a complete manifest."],"exampleFix":"// before\n// version = 0.1\n// after\n// [package]\n// name = \"my-capsule\"\n// version = \"0.1.0\"","handlingStrategy":"validation","validationCode":"fn manifest_has_version(capsule_dir: &Path) -> anyhow::Result<()> {\n    let raw = std::fs::read_to_string(capsule_dir.join(\"Capsule.toml\"))?;\n    let v: toml::Value = toml::from_str(&raw)?;\n    if v.get(\"package\").and_then(|p| p.get(\"version\")).and_then(|n| n.as_str()).is_some() {\n        Ok(())\n    } else {\n        Err(anyhow::anyhow!(\"Capsule.toml missing [package].version string\"))\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Quote the version value in Capsule.toml so TOML parses it as a string, not a float","Add version to every new capsule template","Validate the full [package] table (name and version) in CI before publish"],"tags":["config","toml","manifest","version"],"backgroundTag":"missing-required-config-field","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}