astrid-runtime/astrid · error
capsule archive contains duplicate entry '{requested}'
Error message
capsule archive contains duplicate entry '{requested}' What it means
Each signed pointer must pin the exact GitHub Actions release workflow that produced the version: 'https://github.com/<REPOSITORY>/.github/workflows/release.yml@refs/tags/v<version>'. This ensure! fails when release_workflow_identity deviates from that canonical URL, blocking pointers whose provenance cannot be tied to the official release workflow.
Source
Thrown at crates/astrid-build/src/artifact.rs:224
///
/// Fails when the archive is malformed, contains duplicate matching entries,
/// or the requested entry is absent or not UTF-8.
pub fn read_archive_text(archive_path: &Path, requested: &str) -> anyhow::Result<String> {
let file = File::open(archive_path)
.with_context(|| format!("failed to open {}", archive_path.display()))?;
let mut archive = tar::Archive::new(GzDecoder::new(file));
let mut found = None;
for entry in archive
.entries()
.context("failed to read capsule archive")?
{
let mut entry = entry.context("failed to read capsule archive entry")?;
let path = normalized_entry_path(&entry)?;
if path != requested {
continue;
}
if found.is_some() {
bail!("capsule archive contains duplicate entry '{requested}'");
}
if !entry.header().entry_type().is_file() {
bail!("capsule archive entry '{requested}' is not a regular file");
}
let mut bytes = Vec::new();
entry.read_to_end(&mut bytes)?;
found =
Some(String::from_utf8(bytes).with_context(|| {
format!("capsule archive entry '{requested}' is not valid UTF-8")
})?);
}
found.with_context(|| format!("capsule archive is missing '{requested}'"))
}
fn read_archive(archive_path: &Path) -> anyhow::Result<(Vec<ContentRecord>, Option<Vec<u8>>)> {
let file = File::open(archive_path)
.with_context(|| format!("failed to open {}", archive_path.display()))?;
read_archive_reader(GzDecoder::new(file))View on GitHub (pinned to affd8760f4)
Solutions
- Set release_workflow_identity to exactly format!("https://github.com/{REPOSITORY}/.github/workflows/release.yml@refs/tags/v{version}").
- If the repository or workflow was renamed, regenerate the pointer with current tooling (the check will only pass for the canonical name).
- Re-sign and redistribute the corrected pointer.
Example fix
# before release_workflow_identity = "https://github.com/acme/astrid/.github/workflows/publish.yml@main" # after release_workflow_identity = "https://github.com/acme/astrid/.github/workflows/release.yml@refs/tags/v1.2.3"
Defensive patterns
Strategy: validation
Validate before calling
fn workflow_identity_ok(repo: &str, version: &str, identity: &str) -> bool {
identity == format!("https://github.com/{repo}/.github/workflows/release.yml@refs/tags/v{version}")
} Try / catch
if let Err(e) = parse_channel(&bytes, channel, now) {
if e.to_string().contains("workflow identity is invalid") { eprintln!("use canonical release.yml@refs/tags/v<version>"); }
return Err(e.into());
} Prevention
- Derive identity from REPOSITORY and version constants
- Keep the release workflow file name stable
- Always use refs/tags/v<version> refs
When it happens
Trigger: validate_pointer (via parse_channel or enforce_continuity) sees release.release_workflow_identity differing from the repository/workflow/tag-ref template built from REPOSITORY and the pointer's version.
Common situations: Repository renamed or forked so the URL host/org changed; workflow file renamed (e.g. release.yml to publish.yml); ref written as a SHA or a branch instead of refs/tags/v<version>; pointer copied from another product's channel.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- opaque capsule asset directories cannot be symlinks: {}
- opaque asset path must be a directory: {}
- WASM binary not found at {}
- capsule archive already contains {PROVENANCE_FILE}
- capsule archive contains unsupported entry '{path}'
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/8ffb6b06205aecbc.
Report an issue: GitHub.