{"record":{"id":"da0511bb8d941a9f","repo":"zeroclaw-labs/zeroclaw","slug":"plugin-archive-exceeds-maximum-size-of-max-plugin","errorCode":null,"errorMessage":"plugin archive exceeds maximum size of {MAX_PLUGIN_ZIP_BYTES} bytes","messagePattern":"plugin archive exceeds maximum size of (.+?) bytes","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/plugin_registry.rs","lineNumber":116,"sourceCode":"    Ok(DownloadedPlugin {\n        _temp_dir: temp_dir,\n        plugin_dir,\n        manifest,\n    })\n}\n\nasync fn download_archive_bytes(url: &str) -> Result<Vec<u8>> {\n    let mut response = reqwest::get(url)\n        .await\n        .with_context(|| format!(\"downloading plugin archive {url}\"))?;\n    let status = response.status();\n    if !status.is_success() {\n        bail!(\"plugin archive returned HTTP {status} for {url}\");\n    }\n    if let Some(len) = response.content_length()\n        && len > MAX_PLUGIN_ZIP_BYTES as u64\n    {\n        bail!(\"plugin archive exceeds maximum size of {MAX_PLUGIN_ZIP_BYTES} bytes\");\n    }\n\n    let mut bytes = Vec::new();\n    while let Some(chunk) = response\n        .chunk()\n        .await\n        .context(\"reading plugin archive response body\")?\n    {\n        append_chunk_capped(&mut bytes, &chunk, MAX_PLUGIN_ZIP_BYTES)?;\n    }\n    Ok(bytes)\n}\n\npub(crate) fn collect_capped_chunks<I>(chunks: I, max_bytes: usize) -> Result<Vec<u8>>\nwhere\n    I: IntoIterator<Item = Result<Vec<u8>>>,\n{\n    let mut bytes = Vec::new();","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/src/plugin_registry.rs#L98-L134","documentation":"The plugin archive's declared Content-Length header exceeds MAX_PLUGIN_ZIP_BYTES, so the download is refused before any body bytes are read. This is the early, header-based cap enforced in download_archive_bytes using the saturating content_length check.","triggerScenarios":"The registry entry's archive URL serving a file whose Content-Length exceeds the compiled-in MAX_PLUGIN_ZIP_BYTES limit. Fires immediately after response headers arrive, before chunk streaming begins (the streaming backstop is error 1410).","commonSituations":"Plugin artifact bloated by vendored dependencies or debug symbols; accidentally pointing the entry URL at a full source repo tarball or a debug build; a limit lowered in a downstream fork while reusing upstream registry entries.","solutions":["Replace the archive with a stripped/minimal build under the limit (remove debug symbols, prune vendored deps)","Check the entry URL — a wrong URL may point at a much larger file than intended","If you control the build, rebuild the plugin zip with release profile and excluded heavy assets","If you maintain the toolchain and genuinely need larger artifacts, raise MAX_PLUGIN_ZIP_BYTES and rebuild — but treat it as a policy decision"],"exampleFix":"# before: artifact 900MB with debug symbols\n# after\n[profile.release]\nstrip = true\n# rebuild zip, republish registry entry with the smaller artifact's url + sha256","handlingStrategy":"validation","validationCode":"// Enforce the same header-based cap the downloader applies:\nlet resp = reqwest::head(url).await?;\nif let Some(len) = resp.headers().get(reqwest::header::CONTENT_LENGTH)\n        .and_then(|v| v.to_str().ok()).and_then(|s| s.parse::<u64>().ok()) {\n    assert!(len <= MAX_PLUGIN_ZIP_BYTES as u64, \"archive too large\");\n}","typeGuard":null,"tryCatchPattern":"// On 'plugin archive exceeds maximum size', do not retry — the artifact is\n// objectively over policy. Report and republish a smaller artifact.","preventionTips":["Strip release binaries before zipping plugins","Exclude vendored deps and large assets from registry artifacts","Set a repo-level check on artifact size in the release pipeline"],"tags":["plugin-registry","size-limit","download","security"],"backgroundTag":"download-size-limit-exceeded","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}