janhq/jan · error · Error

Not a CUDA runtime archive: ${archiveName}. Expected cudart-

Error message

Not a CUDA runtime archive: ${archiveName}. Expected cudart-llama-bin-<backend>.(zip|tar.gz)

What it means

Thrown by installCudaRuntime after the path passes the existence/extension pre-check but the basename does not match the regex ^cudart-llama-bin-(.+?)\.(?:tar\.gz|zip)$. The CUDA runtime is shipped as a separately downloadable archive whose filename encodes the target backend (e.g. cudart-llama-bin-vulkan.zip). This guard rejects anything that does not follow that naming contract so the backend type can be parsed safely in the next line.

Source

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

  }

  /**
   * Install the supplementary CUDA runtime DLLs that upstream ships separately
   * (`cudart-llama-bin-<backend>.zip`) into every installed backend of that
   * type, so llama-server can resolve cublas/cudart at launch.
   */
  async installCudaRuntime(path: string): Promise<void> {
    if (
      !(await fs.existsSync(path)) ||
      (!path.endsWith('tar.gz') && !path.endsWith('zip'))
    ) {
      throw new Error(`Invalid path or file ${path}`)
    }

    const archiveName = await basename(path)
    const match = /^cudart-llama-bin-(.+?)\.(?:tar\.gz|zip)$/.exec(archiveName)
    if (!match || !match[1]) {
      throw new Error(
        `Not a CUDA runtime archive: ${archiveName}. Expected cudart-llama-bin-<backend>.(zip|tar.gz)`
      )
    }
    const backendType = match[1]

    const targets = (await getLocalInstalledBackends()).filter(
      (b) => b.backend === backendType
    )
    if (targets.length === 0) {
      throw new Error(
        `No installed "${backendType}" backend found. Install that backend first, then add the CUDA runtime.`
      )
    }

    let installed = 0
    for (const t of targets) {
      const binDir = await joinPath([
        await getBackendDir(t.backend, t.version),

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Verify the archive basename matches exactly: cudart-llama-bin-<backend>.zip or .tar.gz (e.g. cudart-llama-bin-vulkan.zip).
  2. Re-download the CUDA runtime asset from the upstream llama.cpp releases matching your installed backend, do not rename it.
  3. If the file was renamed, rename it back to the original release filename before calling installCudaRuntime.
  4. Confirm you are passing the path to the cudart runtime archive, not the main backend archive or model file.

Example fix

// before
await ext.installCudaRuntime('/downloads/cuda-libs.zip')
// after - rename to the contract the regex expects
await fs.rename('/downloads/cuda-libs.zip', '/downloads/cudart-llama-bin-vulkan.zip')
await ext.installCudaRuntime('/downloads/cudart-llama-bin-vulkan.zip')
Defensive patterns

Strategy: validation

Validate before calling

// Validate the archive name contract BEFORE calling installCudaRuntime
import { basename } from 'path'
const CUDA_RT_RE = /^cudart-llama-bin-(.+?)\.(?:tar\.gz|zip)$/
function assertCudaRuntimeArchive(p: string) {
  const name = basename(p)
  const m = CUDA_RT_RE.exec(name)
  if (!m) throw new Error(`Refusing to call installCudaRuntime: '${name}' is not cudart-llama-bin-<backend>.(zip|tar.gz)`)
  return m[1] // backendType
}
const backendType = assertCudaRuntimeArchive(path)

Type guard

function isCudaRuntimeArchiveName(name: string): boolean {
  return /^cudart-llama-bin-(.+?)\.(?:tar\.gz|zip)$/.test(name)
}

Try / catch

try { await ext.installCudaRuntime(path) }
catch (e) {
  if (/Not a CUDA runtime archive/.test(String(e))) { /* re-fetch the correctly-named asset */ }
  else throw e
}

Prevention

When it happens

Trigger: Calling installCudaRuntime(path) with an archive whose basename is missing the cudart-llama-bin- prefix, has no backend segment (cudart-llama-bin-.zip), uses an unsupported extension (.7z, .tar), or was renamed by the user/download manager (e.g. cudart.zip, llama-cuda-12.zip). The earlier extension/exists guard at line 2956 has already passed, so the file exists and ends in zip|tar.gz but the inner name is wrong.

Common situations: User manually downloaded the wrong artifact (e.g. a full backend bundle instead of the cudart runtime-only zip). CI/upstream renamed the release asset and the extension's downloader saved it under a different name. A proxy mirror re-packed the archive. Cross-platform confusion: pointing at a Windows .zip on Linux where the naming convention differs.

Related errors


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