{"record":{"id":"090a542de2ef1eef","repo":"cube-js/cube","slug":"release-archive-does-not-contain-a-cube-binary","errorCode":null,"errorMessage":"release archive does not contain a cube binary","messagePattern":"release archive does not contain a cube binary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust/cube-cli/src/commands/update.rs","lineNumber":94,"sourceCode":"\n/// Extract the `cube` binary from the release tar.gz archive.\nfn extract_binary(archive: &[u8]) -> Result<Vec<u8>> {\n    let gz = flate2::read::GzDecoder::new(archive);\n    let mut tar = tar::Archive::new(gz);\n    for entry in tar.entries()? {\n        let mut entry = entry?;\n        let path = entry.path()?;\n        let name = path\n            .file_name()\n            .map(|n| n.to_string_lossy().to_string())\n            .unwrap_or_default();\n        if name == \"cube\" || name == \"cube.exe\" {\n            let mut data = Vec::new();\n            std::io::Read::read_to_end(&mut entry, &mut data)?;\n            return Ok(data);\n        }\n    }\n    bail!(\"release archive does not contain a cube binary\");\n}\n\n/// Swap the running executable for the new binary.\n///\n/// The running file is first renamed aside (allowed on every platform,\n/// including Windows, where an in-use file can't be overwritten but can be\n/// renamed), then the new binary is written to the original path. The `.old`\n/// leftover is cleaned up on the next run (see `cleanup_stale_binary`).\nfn replace_current_exe(new_binary: &[u8]) -> Result<()> {\n    let exe = std::env::current_exe().context(\"could not locate the running executable\")?;\n    let old = exe.with_extension(\"old\");\n    let _ = std::fs::remove_file(&old);\n    std::fs::rename(&exe, &old)\n        .with_context(|| format!(\"could not move {} aside\", exe.display()))?;\n\n    if let Err(e) = write_executable(&exe, new_binary) {\n        // Restore the original on failure so the install isn't left broken.\n        let _ = std::fs::rename(&old, &exe);","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube-cli/src/commands/update.rs#L76-L112","documentation":"After downloading the release archive, `cube update` extracts the entry named 'cube' (or 'cube.exe'). If the archive contains no such file, the CLI bails — this indicates a packaging problem in the release artifact or an unexpected archive layout.","triggerScenarios":"Running `cube update` against a release whose archive was packaged incorrectly (binary renamed, missing, or nested under a directory the extractor doesn't traverse).","commonSituations":"Proxy or mirror serving a substitute/truncated archive; a broken or experimental release; corrupted download saved with the archive extension.","solutions":["Re-run `cube update` to re-download a fresh archive","Check the release assets and, if possible, verify the archive contents manually (tar/unzip -l)","Report the broken release and install a known-good version manually"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  run(\"cube update\");\n} catch (e) {\n  if (String(e).includes(\"does not contain a cube binary\")) {\n    console.error(\"Release archive broken; pin a known-good version\");\n  } else throw e;\n}","preventionTips":["Pin CLI versions in CI instead of always updating to latest","Verify release archives manually when a new release ships","Re-download once on failure before escalating (transient truncation)"],"tags":["cli","update","archive","packaging"],"backgroundTag":"unexpected-archive-layout","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}