{"record":{"id":"80b7c897267e44c4","repo":"astrid-runtime/astrid","slug":"capsule-archive-exceeds-50-mb-limit","errorCode":null,"errorMessage":"capsule archive exceeds 50 MB limit","messagePattern":"capsule archive exceeds 50 MB limit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule/install.rs","lineNumber":292,"sourceCode":"// ---------------------------------------------------------------------------\n// GitHub installs — release-artifact download with clone-and-build fallback.\n// ---------------------------------------------------------------------------\n\n/// Stream a `.capsule` asset to `dest`, enforcing a 50 MB ceiling.\nasync fn download_capsule_asset(\n    client: &reqwest::Client,\n    download_url: &str,\n    dest: &Path,\n) -> anyhow::Result<()> {\n    let mut dl = client\n        .get(download_url)\n        .send()\n        .await\n        .context(\"failed to start capsule download\")?;\n    let mut bytes = Vec::new();\n    while let Some(chunk) = dl.chunk().await? {\n        bytes.extend_from_slice(&chunk);\n        anyhow::ensure!(\n            bytes.len() <= 50 * 1024 * 1024,\n            \"capsule archive exceeds 50 MB limit\",\n        );\n    }\n    std::fs::write(dest, &bytes).with_context(|| format!(\"failed to write {}\", dest.display()))?;\n    Ok(())\n}\n\n/// Install from a GitHub source, returning the concrete ref that was\n/// actually resolved and fetched (`Some` on the release-asset path). The\n/// clone-and-build fallback returns `None` — there is no single release\n/// tag it resolved (it builds from whatever `--depth 1` HEAD it cloned).\nasync fn install_from_github(\n    url: &str,\n    name_hint: Option<&str>,\n    version: Option<&str>,\n    tag: Option<&str>,\n    context: InstallContext<'_>,","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule/install.rs#L274-L310","documentation":"Raised in download_capsule_asset when the streamed capsule download accumulates more than 50 MB (50 * 1024 * 1024 bytes). The limit is enforced with anyhow::ensure inside the chunk loop to cap memory use and reject oversized or unexpected archives.","triggerScenarios":"Downloading a release asset that is genuinely larger than 50 MB, a mis-pointed URL that returns a huge non-capsule file, or a slow/broken proxy feeding an unbounded stream.","commonSituations":"Installing a capsule whose latest release asset grew past the limit after a version bump, accidentally targeting a source tarball instead of the capsule archive, or a mirror serving the wrong artifact.","solutions":["Pin the capsule to an older release whose archive is under 50 MB","Verify the URL points at the correct capsule archive asset, not a tarball/source","Contact the capsule publisher to shrink or split the archive; the 50 MB limit is a hard client-side cap"],"exampleFix":"// before\n--from https://github.com/org/repo/releases/latest/download/capsule-huge.bin\n// after\n--from https://github.com/org/repo/releases/download/v1.2.0/capsule.tar.gz","handlingStrategy":"validation","validationCode":"let size = reqwest::head(url).await?.content_length();\nif let Some(n) = size {\n    if n > 50 * 1024 * 1024 { eprintln!(\"asset too large ({n} bytes)\"); std::process::exit(1); }\n}","typeGuard":null,"tryCatchPattern":"match resolve_capsule_to_file(...).await { Err(e) if e.to_string().contains(\"50 MB limit\") => { eprintln!(\"capsule archive too large; pin a smaller release\"); Err(e) }, other => other }","preventionTips":["HEAD-check Content-Length before downloading large assets","Pin capsule installs to known releases with vetted archive sizes","Ensure the URL targets the capsule archive, not a source tarball"],"tags":["download","size-limit","http"],"backgroundTag":"file-size-limit-exceeded","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"}