janhq/jan · warning · Error

No update available

Error message

No update available

What it means

Thrown by TauriUpdaterService.downloadAndInstallWithProgress when the Tauri updater's check() returns null, i.e. no update is available at the moment the user triggered install. It guards against calling downloadAndInstall() on a null Update object.

Source

Thrown at web-app/src/services/updater/tauri.ts:147

    try {
      const update = await check()
      if (update) {
        await update.downloadAndInstall()
        // Note: Auto-restart happens after installation
      }
    } catch (error) {
      console.error('Error installing update in Tauri:', error)
      throw error
    }
  }

  async downloadAndInstallWithProgress(
    progressCallback: (event: UpdateProgressEvent) => void
  ): Promise<void> {
    try {
      const update = await check()
      if (!update) {
        throw new Error('No update available')
      }

      // Use Tauri's downloadAndInstall with progress callback
      await update.downloadAndInstall((event) => {
        try {
          // Forward the event to the callback
          progressCallback(event as UpdateProgressEvent)
        } catch (callbackError) {
          console.warn('Error in download progress callback:', callbackError)
        }
      })
    } catch (error) {
      console.error('Error downloading update with progress in Tauri:', error)
      throw error
    }
  }
}

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Re-run check() immediately before enabling/triggering the install action; disable the control when it returns null.
  2. Surface 'You're up to date' to the user instead of throwing when update is null.

Example fix

// before: throw on null update
const update = await check()
if (!update) throw new Error('No update available')
// after: treat as a benign no-op
const update = await check()
if (!update) { setUpToDate(true); return }
Defensive patterns

Strategy: validation

Validate before calling

const update = await check()
if (!update) { setUpToDate(true); return }

Type guard

function hasUpdate(u: Update | null): u is Update { return u !== null }

Try / catch

try {
  await updater.downloadAndInstallWithProgress(cb)
} catch (e) {
  if (e instanceof Error && e.message === 'No update available') showUpToDate()
  else throw e
}

Prevention

When it happens

Trigger: User clicks 'download & install with progress' but check() returns null - the app is already on the latest version, or the update was pulled between the last check and the install action.

Common situations: User already updated since the last check; update feed rolled back; race between the check UI and the install action; the update endpoint returned no update.

Related errors


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