janhq/jan · error · Error

Backend update failed: ${result.reason}

Error message

Backend update failed: ${result.reason}

What it means

Thrown when `extension.updateBackend(targetBackendString)` resolves with `{ wasUpdated: false, reason }` where `reason` is present and not the benign `'in_progress'`. The extension explicitly reported a failure (e.g. `'error'`, a download hash mismatch, disk-full, etc.), and the raw reason is surfaced.

Source

Thrown at web-app/src/hooks/useBackendUpdater.ts:389

        syncStateToOtherInstances(newState)
      } else if (
        result?.wasUpdated === false &&
        (result.reason === 'in_progress' || typeof result.reason === 'undefined')
      ) {
        // Benign no-op (e.g., another update is already in progress or the
        // extension returned a no-op response without a reason). Do not treat
        // this as a failure; just clear the local isUpdating flag.
        setUpdateState((prev) => ({
          ...prev,
          isUpdating: false,
        }))
      } else if (
        result?.wasUpdated === false &&
        result.reason &&
        result.reason !== 'in_progress'
      ) {
        // Explicit failure reason from extension: surface as an error.
        throw new Error(`Backend update failed: ${result.reason}`)
      } else {
        throw new Error('Backend update failed')
      }
    } catch (error) {
      console.error('Error updating backend:', error)
      setUpdateState((prev) => ({
        ...prev,
        isUpdating: false,
      }))
      throw error
    }
  }, [updateState.updateInfo, updateState.isUpdating, syncStateToOtherInstances])

  const installBackend = useCallback(async (filePath: string) => {
    try {
      // Get llamacpp extension instance
      const allExtensions = ExtensionManager.getInstance().listExtensions()
      const llamacppExtension =

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Check the extension's logs for the underlying `reason` value to identify network vs. disk vs. checksum.
  2. Free disk space and retry; backends are several hundred MB.
  3. If behind a proxy, ensure HTTPS egress to the backend CDN is allowed.
  4. Retry — transient download failures often succeed on a second attempt.

Example fix

// before
} else if (result?.wasUpdated === false && result.reason && result.reason !== 'in_progress') {
  throw new Error(`Backend update failed: ${result.reason}`)
}

// after
} else if (result?.wasUpdated === false && result.reason && result.reason !== 'in_progress') {
  const hint = /network|download|fetch/i.test(result.reason)
    ? ' Check your connection and retry.'
    : /space|disk|full/i.test(result.reason)
      ? ' Free disk space and retry.'
      : ''
  throw new Error(`Backend update failed: ${result.reason}.${hint}`)
}
Defensive patterns

Strategy: try-catch

Type guard

function isFailedUpdateResult(r: unknown): r is { wasUpdated: false; reason: string } {
  return !!r && (r as any).wasUpdated === false && typeof (r as any).reason === 'string' && (r as any).reason !== 'in_progress'
}

Try / catch

try {
  const result = await extension.updateBackend?.(targetBackendString) as BackendUpdateResult | undefined
  if (isFailedUpdateResult(result)) {
    toast.error('Backend update failed', { description: result.reason })
    return
  }
} catch (error) {
  console.error('updateBackend:', error)
  throw error
}

Prevention

When it happens

Trigger: The backend download failed inside the extension: network error fetching the backend binary, checksum mismatch, insufficient disk space, the target version doesn't exist for the platform, or the extension's internal update routine threw and mapped it to `reason: 'error'`.

Common situations: Transient network outage during the backend download; GitHub/CDN hosting the binary is unreachable; disk full; proxy blocking the download URL; platform-unsupported backend variant.

Related errors


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