{"record":{"id":"f3e1225fd5dc7669","repo":"jdx/mise","slug":"brew-cask-nested-archive-depth-exceeds-max-neste","errorCode":null,"errorMessage":"brew-cask: nested archive depth exceeds {MAX_NESTED_CASK_ARCHIVES}","messagePattern":"brew-cask: nested archive depth exceeds (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/fetch.rs","lineNumber":341,"sourceCode":"            .to_string();\n        let nested = extract_dir.with_file_name(format!(\n            \".{}-nested-{depth}\",\n            extract_dir\n                .file_name()\n                .and_then(|name| name.to_str())\n                .unwrap_or(\"cask\")\n        ));\n        file::remove_all(&nested)?;\n        file::rename(&archive, &nested)?;\n        file::remove_all(extract_dir)?;\n        file::create_dir_all(extract_dir)?;\n        let result = extract_nested_cask_archive(&nested, extract_dir, &filename, pr);\n        let cleanup = file::remove_all(&nested);\n        result?;\n        cleanup?;\n    }\n    if single_nested_cask_archive(extract_dir)?.is_some() {\n        bail!(\"brew-cask: nested archive depth exceeds {MAX_NESTED_CASK_ARCHIVES}\");\n    }\n    Ok(())\n}\n\npub(super) fn single_nested_cask_archive(root: &Path) -> Result<Option<PathBuf>> {\n    let mut entries = std::fs::read_dir(root)?.filter(|entry| match entry {\n        Ok(entry) => entry.file_name() != \"__MACOSX\",\n        Err(_) => true,\n    });\n    let Some(entry) = entries.next().transpose()? else {\n        return Ok(None);\n    };\n    if entries.next().is_some() || !entry.file_type()?.is_file() {\n        return Ok(None);\n    }\n    let path = entry.path();\n    let filename = entry.file_name();\n    let filename = filename","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/cask/fetch.rs#L323-L359","documentation":"Nested cask archive extraction is depth-limited by MAX_NESTED_CASK_ARCHIVES. After extracting a nested archive, the code re-checks the extract dir and if it still contains a single archive (i.e., another layer would need extraction), the depth budget is exhausted and this error is thrown. It guards against archives nested arbitrarily deep, which could recurse indefinitely.","triggerScenarios":"A downloaded cask archive contains an archive, which contains another archive, and so on past the MAX_NESTED_CASK_ARCHIVES limit; `extract_nested_cask_archives` (called from `extract_archive`) unwraps each layer via `extract_nested_cask_archive` and then `single_nested_cask_archive` finds yet another archive.","commonSituations":"Upstream ships a zip inside a tar.gz inside a dmg; a malformed or adversarial cask artifact; a newly increased nesting depth in an upstream release that outgrows the constant.","solutions":["Manually unpack the artifact to inspect how many layers it has and confirm it is legitimate","Extract the outer layers yourself and stage the final payload, or fix the cask to point at a single-layer archive","Report/patch the cask definition so it references a non-recursively-nested artifact","If the nesting is legitimate, raise MAX_NESTED_CASK_ARCHIVES in the fetcher"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Inspect layer count before installing\nlet mut depth = 0; let mut cur = downloaded.clone();\nwhile is_archive(&cur) { cur = peek_inner(&cur)?; depth += 1; }\nassert!(depth <= MAX_NESTED_CASK_ARCHIVES, \"too many nested archives\");","typeGuard":"fn within_depth(n: usize) -> bool { n <= MAX_NESTED_CASK_ARCHIVES }","tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"nested archive depth\") => manually_extract_outer_layers(),\n    other => other?,\n}","preventionTips":["Prefer cask artifacts that are single-layer archives","Validate artifact structure once per upstream version in CI","Avoid casks that repack archives inside archives"],"tags":["brew-cask","archive","recursion","depth-limit"],"backgroundTag":"value-out-of-range","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}