{"record":{"id":"f304f2c2a15d6db6","repo":"astrid-runtime/astrid","slug":"capsule-version-must-not-contain-surrounding","errorCode":null,"errorMessage":"capsule '{}': version must not contain surrounding whitespace","messagePattern":"capsule '(.+?)': version must not contain surrounding whitespace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/distro/validate.rs","lineNumber":157,"sourceCode":"            anyhow::bail!(\"duplicate capsule name '{}'\", cap.name);\n        }\n        // Distros compose *released* capsules. `branch`/`rev` selectors\n        // can only be honored by compiling from a git ref — the exact\n        // toolchain dependency offline/headless distro seeding exists to\n        // remove. Reject them: a distro must pin a released `version` or\n        // `tag`. (Git-ref installs remain available via the standalone\n        // `astrid capsule install` command.)\n        if cap.branch.is_some() || cap.rev.is_some() {\n            anyhow::bail!(\n                \"capsule '{}': branch/rev require building from source and are not allowed in a \\\n                 distro manifest — pin a released `version` or `tag` (git-ref installs are \\\n                 available via `astrid capsule install`).\",\n                cap.name,\n            );\n        }\n        let version = cap.version.trim();\n        if cap.version != version {\n            anyhow::bail!(\n                \"capsule '{}': version must not contain surrounding whitespace\",\n                cap.name\n            );\n        }\n        if !version.is_empty() && Version::parse(version).is_err() {\n            anyhow::bail!(\n                \"capsule '{}': version '{}' is not valid semver\",\n                cap.name,\n                cap.version\n            );\n        }\n        let tag = cap.tag.as_deref().map(str::trim);\n        if let Some(raw_tag) = cap.tag.as_deref()\n            && raw_tag != raw_tag.trim()\n        {\n            anyhow::bail!(\n                \"capsule '{}': tag must not contain surrounding whitespace\",\n                cap.name","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/distro/validate.rs#L139-L175","documentation":"Capsule versions must be clean, so validate_manifest compares the raw `cap.version` against its trimmed form and bails when they differ (leading/trailing whitespace). Whitespace-padded versions would produce surprising semver parse results or mismatched resolution keys downstream.","triggerScenarios":"A `[[capsules]]` entry with `version = \" 1.2.0 \"` or `\"1.2.0\\n\"` — any leading/trailing space, tab, or newline in the version string.","commonSituations":"Hand-editing manifests where editors leave trailing spaces; copy-pasting a version from a webpage or terminal with trailing whitespace; YAML/TOML string values that preserved padding.","solutions":["Strip surrounding whitespace from the `version` value in the manifest.","Enable trim-on-save / trailing-whitespace highlighting in your editor for manifest files.","If the manifest is generated, trim the version string at generation time."],"exampleFix":"# before\n[[capsules]]\nname = \"http\"\nversion = \" 1.2.0 \"\n\n# after\n[[capsules]]\nname = \"http\"\nversion = \"1.2.0\"","handlingStrategy":"validation","validationCode":"for cap in &manifest.capsules {\n    if cap.version != cap.version.trim() {\n        panic!(\"capsule '{}': trim version whitespace\", cap.name);\n    }\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = validate_manifest(&manifest) {\n    if e.to_string().contains(\"surrounding whitespace\") {\n        eprintln!(\"strip padding from version: {e}\");\n    }\n}","preventionTips":["Enable trailing-whitespace trimming on save for manifest files","Trim interpolated variables when generating manifests","Avoid copy-pasting version strings from terminals/web pages without trimming"],"tags":["cli","manifest","whitespace","validation"],"backgroundTag":"invalid-argument-format","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"}