laurent22/joplin · warning · Error

Could not check for updates. Please try again later (Error $

Error message

Could not check for updates. Please try again later (Error ${status}).

What it means

Thrown by handleReleaseResponseError as the catch-all when the GitHub releases API returns any HTTP error status that is not a recognized rate-limit (403/429 without 'rate limit' in the body, or any other 4xx/5xx). The status code is interpolated into the message.

Source

Thrown at packages/app-desktop/utils/checkForUpdatesUtils.ts:148

	}

	const output: Release = {
		version: version,
		downloadUrl: downloadUrl,
		notes: cleanUpReleaseNotes(fullReleaseNotes),
		pageUrl: release.html_url,
		prerelease: release.prerelease,
	};

	return output;
};

export const handleReleaseResponseError = (status: number, responseText: string): never => {
	if ((status === 403 || status === 429) && responseText.toLowerCase().includes('rate limit')) {
		throw new Error('Could not check for updates. The server rate limit has been exceeded — this is a temporary issue, please try again later.');
	}

	throw new Error(`Could not check for updates. Please try again later (Error ${status}).`);
};

View on GitHub (pinned to 2654b33620)

Solutions

  1. Retry after a short wait — transient 5xx errors self-resolve.
  2. Check network connectivity and proxy configuration (HTTPS_PROXY / corporate TLS inspection).
  3. Verify the release feed URL is correct and the target repo has published releases.
  4. If persistent, inspect the raw response body logged upstream to diagnose the specific status.

Example fix

// before
throw new Error(`Could not check for updates. Please try again later (Error ${status}).`);

// after — surface responseText excerpt for diagnosis
throw new Error(`Could not check for updates (HTTP ${status}). Server said: ${responseText.slice(0, 120)}`);
Defensive patterns

Strategy: retry

Validate before calling

const status = await fetchReleaseStatus();
if (status >= 500) {
  // server error — retry with backoff
  await backoffRetry(() => checkForUpdates());
} else if (status >= 400) {
  // client/config error — do not retry blindly
}

Type guard

function isTransientError(status: number): boolean {
  return status === 408 || status === 425 || status === 500 || status === 502 || status === 503 || status === 504;
}

Try / catch

try {
  await checkForUpdates();
} catch (e) {
  const match = e.message.match(/Error (\d+)/);
  const status = match ? Number(match[1]) : 0;
  if (isTransientError(status)) {
    // retry with exponential backoff
  } else {
    // surface to user / log responseText
  }
}

Prevention

When it happens

Trigger: checkForUpdates receives a non-2xx response (e.g. 404 if the release endpoint moved, 500/502/503 server errors, 401 auth errors) that does not match the rate-limit condition; handleReleaseResponseError throws with the raw status.

Common situations: GitHub is temporarily unavailable (5xx); a corporate proxy intercepts and returns a non-200; the configured release URL points to a repo with no releases (404); DNS/network failure surfacing as a captured status; plugin-based updaters pointing at a wrong endpoint.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/14084f97549061fd. Report an issue: GitHub.