janhq/jan · error · Error

Failed to decompress archive: ${String(e)}

Error message

Failed to decompress archive: ${String(e)}

What it means

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.

Source

Thrown at extensions/llamacpp-extension/src/index.ts:2889

    if (!version || !backend) {
      throw new Error(`Invalid backend archive name: ${archiveName}`)
    }

    // Include prefix in the backend identifier if present
    const backendIdentifier = prefix ? `${prefix}${backend}` : backend

    logger.info(
      `Detected prefix: ${prefix || 'none'}, version: ${version}, backend: ${backendIdentifier}`
    )

    const backendDir = await getBackendDir(backendIdentifier, version)

    try {
      await invoke('decompress', { path: path, outputDir: backendDir })
    } catch (e) {
      logger.error(`Failed to install: ${String(e)}`)
      throw new Error(`Failed to decompress archive: ${String(e)}`)
    }

    const serverName =
      platformName === 'win' ? 'llama-server.exe' : 'llama-server'
    const expectedBinDir = await joinPath([backendDir, 'build', 'bin'])
    const expectedBinPath = await joinPath([expectedBinDir, serverName])

    // Normalize varying archive layouts to `build/bin/`: Jan tarballs already
    // ship it; upstream Linux tarballs nest under `llama-bXXXX/`; upstream
    // Windows zips are flat with the binary + DLLs at the root.
    if (!(await fs.existsSync(expectedBinPath))) {
      const foundDir = await findLlamaServerDir(backendDir, serverName)
      if (!foundDir) {
        await fs.rm(backendDir)
        throw new Error(
          'Not a supported backend archive! Missing llama-server binary.'
        )
      }

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Re-download the archive — a CRC or truncation error usually means the file itself is corrupt.
  2. Verify the Jan data folder (backend directory parent) is writable and has sufficient free space.
  3. Temporarily disable antivirus to see if it is blocking extraction.
  4. Inspect the underlying error message (String(e)) for the exact Rust-side failure reason.
Defensive patterns

Strategy: try-catch

Validate before calling

import fs from 'node:fs'

function canWriteTo(dir: string): boolean {
  try { fs.accessSync(dir, fs.constants.W_OK); return true } catch { return false }
}

// Before install, verify output directory is writable:
if (!canWriteTo(backendDir)) {
  throw new Error(`Cannot write to backend directory: ${backendDir}`)
}

Try / catch

try {
  await invoke('decompress', { path, outputDir: backendDir })
} catch (e) {
  if (String(e).includes('CRC') || String(e).includes('corrupt')) {
    // Re-download the archive
    await reDownload(path)
    await invoke('decompress', { path, outputDir: backendDir })
  } else {
    throw new Error(`Failed to decompress archive: ${String(e)}`)
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12). Data as JSON: /api/errors/830a572ad64edc02. Report an issue: GitHub.