{"record":{"id":"929cb5dc2e4f043b","repo":"astrid-runtime/astrid","slug":"capsule-tag-must-not-contain-surrounding-whi","errorCode":null,"errorMessage":"capsule '{}': tag must not contain surrounding whitespace","messagePattern":"capsule '(.+?)': tag must not contain surrounding whitespace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/distro/validate.rs","lineNumber":173,"sourceCode":"        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\n            );\n        }\n        if matches!(tag, Some(\"\")) {\n            anyhow::bail!(\"capsule '{}': tag must not be empty\", cap.name);\n        }\n        if version.is_empty() && tag.is_none() {\n            anyhow::bail!(\n                \"capsule '{}': distro capsules require a concrete released version or tag\",\n                cap.name\n            );\n        }\n    }\n\n    // At least one uplink.\n    let has_uplink = manifest\n        .capsules","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/distro/validate.rs#L155-L191","documentation":"Like versions, capsule tags must be free of surrounding whitespace: validate_manifest trims the optional `tag` string and bails when the raw value differs from its trimmed form. Tags are used verbatim to resolve released capsule artifacts, so padded tags would fail lookup.","triggerScenarios":"A `[[capsules]]` entry with `tag = \" v1.2.0 \"` or a tag containing a trailing newline/tab.","commonSituations":"Copy-pasting git tags from terminals or docs with trailing spaces; generated manifests that interpolate untrimmed variables; editors inserting trailing whitespace on save.","solutions":["Strip surrounding whitespace from the `tag` value in the manifest.","Trim the tag at generation time if the manifest is scripted.","Re-run validation; note an all-whitespace tag will then hit the separate 'tag must not be empty' error — remove it instead if unintended."],"exampleFix":"# before\n[[capsules]]\nname = \"http\"\ntag = \" v1.2.0 \"\n\n# after\n[[capsules]]\nname = \"http\"\ntag = \"v1.2.0\"","handlingStrategy":"validation","validationCode":"for cap in &manifest.capsules {\n    if let Some(t) = &cap.tag {\n        if t != t.trim() {\n            panic!(\"capsule '{}': trim tag whitespace\", cap.name);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = validate_manifest(&manifest) {\n    if e.to_string().contains(\"tag must not contain surrounding whitespace\") {\n        eprintln!(\"strip padding from tag: {e}\");\n    }\n}","preventionTips":["Trim tags when generating manifests from variables","Avoid copying tags from terminal output without trimming","Enable whitespace-trimming editor plugins for TOML/YAML"],"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"}