janhq/jan · error · Error

Invalid backend string format: "${targetBackendString}". Exp

Error message

Invalid backend string format: "${targetBackendString}". Expected "version/backend".

What it means

Format validation in runUpdate: after confirming the string is non-empty, it is split on '/' and checked for exactly two non-empty, non-whitespace parts. A string that doesn't match 'version/backend' (e.g. 'v1', 'v1/', '/backend', 'a/b/c') throws.

Source

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

    this.isUpdatingBackend = true
    const startedAt = Date.now()
    const from = this.config.version_backend
    let previous: BackendSelection | undefined

    try {
      if (!targetBackendString)
        throw new Error(
          `Invalid backend string: ${targetBackendString} supplied to update function`
        )

      const backendParts = targetBackendString.split('/')

      if (
        backendParts.length !== 2 ||
        !backendParts[0]?.trim() ||
        !backendParts[1]?.trim()
      ) {
        throw new Error(
          `Invalid backend string format: "${targetBackendString}". Expected "version/backend".`
        )
      }

      const [rawVersion, rawBackend] = backendParts
      const version = rawVersion.trim()
      const backend = rawBackend.trim()

      // Normalize the target backend string to use trimmed values
      targetBackendString = `${version}/${backend}`

      logger.info(
        `Updating backend to ${targetBackendString} (backend type: ${backend})`
      )

      previous = await this.captureBackendSelection()

      // Download new backend using the original asset/backend name

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Construct the backend string as `${version}/${backend}` from validated non-empty components.
  2. Add a regex pre-check (e.g. /^\S+\/\S+$/) before calling runUpdate.
  3. Inspect the stored backend preference format and migrate legacy values to 'version/backend'.

Example fix

// before
this.runUpdate(`${version}/${backend}`)  // backend might be ''
// after
if (!/^\S+\/\S+$/.test(`${version}/${backend}`)) throw new Error('Bad format')
this.runUpdate(`${version}/${backend}`)
Defensive patterns

Strategy: validation

Validate before calling

const BACKEND_STRING_RE = /^\S+\/\S+$/

function isValidBackendFormat(s: string): boolean {
  return BACKEND_STRING_RE.test(s)
}

// Before calling runUpdate:
if (!isValidBackendFormat(targetBackendString)) {
  throw new Error(`Expected 'version/backend', got '${targetBackendString}'`)
}

Type guard

function isVersionBackendString(s: unknown): s is string {
  return typeof s === 'string' && /^\S+\/\S+$/.test(s)
}

Prevention

When it happens

Trigger: targetBackendString has zero, one, or more than one '/'; either the version or backend segment is empty or whitespace-only after trim. Examples: 'b1234', 'b1234/', '/cuda-12.4', 'v1/cuda/extra'.

Common situations: Backend string assembled from separate fields with one left blank; a stored preference string that was partially overwritten; user-typed or API-supplied value that doesn't follow the convention.

Related errors


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