Yeachan-Heo/oh-my-codex · error

manifest_url_basename_mismatch

manifest_url_basename_mismatch

Error message

[native-assets] manifest_url_basename_mismatch: ${asset.download_url}

What it means

The download URL's last path segment must equal the archive basename and its protocol must be http or https. This ties the URL to the validated archive identity and blocks exotic protocols.

Source

Thrown at src/native-assets/policy.ts:187

    const key = nativeReleaseAssetLogicalKey(asset);
    if (logicalKeys.has(key)) throw policyError('manifest_duplicate_logical_key', asset.archive);
    logicalKeys.add(key);
    const basename = nativeReleaseAssetBasename(asset);
    if (asset.archive !== basename || !nativeArchiveSuffix(basename)) {
      throw policyError('manifest_archive_invalid', asset.archive);
    }
    if (archiveHintMismatch(asset, basename)) throw policyError('manifest_archive_hint_mismatch', basename);
    if (basenames.has(basename)) throw policyError('manifest_duplicate_archive_basename', basename);
    basenames.add(basename);
    let downloadUrl: URL;
    try {
      downloadUrl = new URL(asset.download_url);
    } catch {
      throw policyError('manifest_invalid_url', asset.download_url);
    }
    if ((downloadUrl.protocol !== 'https:' && downloadUrl.protocol !== 'http:')
      || downloadUrl.pathname.split('/').at(-1) !== basename) {
      throw policyError('manifest_url_basename_mismatch', asset.download_url);
    }
  }
}

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Make the URL's final path segment exactly match asset.archive
  2. Use http/https only
  3. If the host rewrites filenames, download to a temp name and rename, and update the manifest to the real URL

Example fix

// before
"archive":"omxd-linux-x64.tar.zst",
"download_url":"https://dl.acme.io/latest?asset=omxd-linux-x64"
// after
"archive":"omxd-linux-x64.tar.zst",
"download_url":"https://dl.acme.io/v1/omxd-linux-x64.tar.zst"
Defensive patterns

Strategy: validation

Validate before calling

const ok = assets.every((a) => {
  try { const u = new URL(a.download_url); return (u.protocol==='https:'||u.protocol==='http:') && u.pathname.split('/').at(-1)===a.archive; } catch { return false; }
});

Prevention

When it happens

Trigger: download_url whose pathname ends in a different filename than asset.archive, or protocols like file: or ftp:.

Common situations: Redirect-style URLs, query-string-only links, uploading the file under a different name than declared, or a mirror URL that appends tokens after the filename in the path.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/f55f433ddda96428. Report an issue: GitHub.