iOfficeAI/AionUi · error · Error

update.errors.cdnManifestFailed

update.errors.cdnManifestFailed

Error message

update.errors.cdnManifestFailed

What it means

Thrown by fetchCdnManifest when fetching the CDN update manifest URL returns a non-OK HTTP status. This is the first failure point of the CDN manifest path (before parsing), with the status code interpolated into the message; the request uses a custom User-Agent and an abort timeout.

Source

Thrown at packages/desktop/src/process/bridge/updateBridge.ts:370

/**
 * Fetch and parse the authoritative CDN channel manifest for the current
 * platform/arch. Any failure here fails the manual check — the CDN is the
 * single source of truth for "is there an update".
 */
const fetchCdnManifest = async (): Promise<CdnLatestManifest> => {
  const url = `${CDN_BASE_URL}/${resolveCdnChannelFile()}`;
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), CDN_MANIFEST_TIMEOUT_MS);

  log.info('[manual-update] Checking CDN manifest:', url);
  try {
    const res = await fetch(url, {
      headers: { 'User-Agent': DEFAULT_USER_AGENT },
      signal: controller.signal,
    });
    if (!res.ok) {
      throw new Error((await getI18n()).t('update.errors.cdnManifestFailed', { status: res.status }));
    }
    const manifest = parseCdnManifest(await res.text());
    if (!manifest) {
      throw new Error((await getI18n()).t('update.errors.cdnManifestInvalid'));
    }
    log.info('[manual-update] CDN manifest resolved:', {
      url,
      version: manifest.version,
      files: manifest.files.length,
    });
    return manifest;
  } catch (err: unknown) {
    if (err instanceof Error && err.name === 'AbortError') {
      throw new Error((await getI18n()).t('update.errors.cdnManifestTimeout'), { cause: err });
    }
    throw err;
  } finally {
    clearTimeout(timeoutId);

View on GitHub (pinned to 711aa0550e)

Solutions

  1. Read the {status}: 404 => manifest missing (wait for release publish or fix URL), 403 => permissions, 5xx => CDN-side
  2. curl -I the manifest URL to confirm reachability and status
  3. Fix the CDN manifest URL if the domain/path changed
  4. Retry shortly after a release — publish propagation can lag
  5. If 403, make the bucket/object public or serve via signed URLs

Example fix

# before
manifestUrl = https://cdn.example.com/old-path/manifest.json  # 404
# after
manifestUrl = https://cdn.example.com/aionui/manifest.json
Defensive patterns

Strategy: fallback

Validate before calling

const isManifestUrlReachable = async (url: string): Promise<boolean> => {
  try { const r = await fetch(url, { method: 'HEAD' }); return r.ok; } catch { return false; }
};
if (!(await isManifestUrlReachable(manifestUrl))) {
  // skip CDN path, use GitHub releases fallback
}

Try / catch

try {
  const manifest = await fetchCdnManifest(url);
} catch (err) {
  if (err instanceof Error && err.message.includes('cdnManifestFailed')) {
    const releases = await fetchGitHubReleases(repo); // fallback channel
  } else throw err;
}

Prevention

When it happens

Trigger: Calling fetchCdnManifest when the manifest endpoint returns 404 (wrong URL/manifest not published yet), 403 (bucket permissions/WAF), 5xx (CDN error), or when a proxy intercepts the request. The status value tells which.

Common situations: Release not yet published to CDN when the client checks (404 race right after tagging); CDN bucket made private; wrong manifest URL after a domain migration; regional CDN node failure; WAF blocking the custom User-Agent.

Related errors


AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28). Data as JSON: /api/errors/c8f586546bca2712. Report an issue: GitHub.