{"record":{"id":"830a572ad64edc02","repo":"janhq/jan","slug":"failed-to-decompress-archive-string-e","errorCode":null,"errorMessage":"Failed to decompress archive: ${String(e)}","messagePattern":"Failed to decompress archive: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/llamacpp-extension/src/index.ts","lineNumber":2889,"sourceCode":"\n    if (!version || !backend) {\n      throw new Error(`Invalid backend archive name: ${archiveName}`)\n    }\n\n    // Include prefix in the backend identifier if present\n    const backendIdentifier = prefix ? `${prefix}${backend}` : backend\n\n    logger.info(\n      `Detected prefix: ${prefix || 'none'}, version: ${version}, backend: ${backendIdentifier}`\n    )\n\n    const backendDir = await getBackendDir(backendIdentifier, version)\n\n    try {\n      await invoke('decompress', { path: path, outputDir: backendDir })\n    } catch (e) {\n      logger.error(`Failed to install: ${String(e)}`)\n      throw new Error(`Failed to decompress archive: ${String(e)}`)\n    }\n\n    const serverName =\n      platformName === 'win' ? 'llama-server.exe' : 'llama-server'\n    const expectedBinDir = await joinPath([backendDir, 'build', 'bin'])\n    const expectedBinPath = await joinPath([expectedBinDir, serverName])\n\n    // Normalize varying archive layouts to `build/bin/`: Jan tarballs already\n    // ship it; upstream Linux tarballs nest under `llama-bXXXX/`; upstream\n    // Windows zips are flat with the binary + DLLs at the root.\n    if (!(await fs.existsSync(expectedBinPath))) {\n      const foundDir = await findLlamaServerDir(backendDir, serverName)\n      if (!foundDir) {\n        await fs.rm(backendDir)\n        throw new Error(\n          'Not a supported backend archive! Missing llama-server binary.'\n        )\n      }","sourceCodeStart":2871,"sourceCodeEnd":2907,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/extensions/llamacpp-extension/src/index.ts#L2871-L2907","documentation":"Wrapping error when the Tauri 'decompress' IPC command fails during archive extraction. The underlying error from the Rust-side decompress handler is captured and re-thrown with a 'Failed to decompress archive' prefix. The extracted backend directory may be in an incomplete state.","triggerScenarios":"The decompress command throws: the archive is corrupted (CRC error), the output directory is not writable, disk space runs out mid-extraction, the archive uses an unsupported compression method, or a permission issue blocks file creation.","commonSituations":"Corrupted or truncated download that passed path/format checks; antivirus blocking extraction; read-only destination directory; disk full during extraction of a large CUDA backend archive.","solutions":["Re-download the archive — a CRC or truncation error usually means the file itself is corrupt.","Verify the Jan data folder (backend directory parent) is writable and has sufficient free space.","Temporarily disable antivirus to see if it is blocking extraction.","Inspect the underlying error message (String(e)) for the exact Rust-side failure reason."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import fs from 'node:fs'\n\nfunction canWriteTo(dir: string): boolean {\n  try { fs.accessSync(dir, fs.constants.W_OK); return true } catch { return false }\n}\n\n// Before install, verify output directory is writable:\nif (!canWriteTo(backendDir)) {\n  throw new Error(`Cannot write to backend directory: ${backendDir}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await invoke('decompress', { path, outputDir: backendDir })\n} catch (e) {\n  if (String(e).includes('CRC') || String(e).includes('corrupt')) {\n    // Re-download the archive\n    await reDownload(path)\n    await invoke('decompress', { path, outputDir: backendDir })\n  } else {\n    throw new Error(`Failed to decompress archive: ${String(e)}`)\n  }\n}","preventionTips":["Verify the archive integrity (checksum or size) before attempting decompression.","Ensure the output directory is writable and has sufficient free space.","Log the underlying decompress error for diagnosis — the Rust-side message is the key signal."],"tags":["backend","decompression","archive","filesystem","tauri","typescript"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}