Yeachan-Heo/oh-my-codex · error

manifest_binary_product_mismatch

manifest_binary_product_mismatch

Error message

[native-assets] manifest_binary_product_mismatch: ${asset.binary}

What it means

During validation of a native release manifest, the declared asset binary name does not match the canonical binary name for the asset's product/platform. The policy module computes the expected binary via nativeProductBinaryName/nativeProductBinaryPath and rejects any mismatch to guarantee every archive ships the correct executable.

Source

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

    const requiredStrings: Array<keyof NativeReleaseAssetPolicyInput> = [
      'product', 'platform', 'arch', 'target', 'archive', 'binary', 'binary_path', 'sha256', 'download_url',
    ];
    if (requiredStrings.some((field) => !requiredString(asset[field]))) {
      throw policyError('manifest_invalid_asset', asset.archive || 'unknown');
    }
    const assetSize = asset.size;
    if (!/^[a-f0-9]{64}$/.test(asset.sha256) || assetSize === undefined || !Number.isSafeInteger(assetSize) || assetSize <= 0) {
      throw policyError('manifest_invalid_integrity', asset.archive);
    }
    const mapping = nativeTargetMapping(asset.target);
    if (!mapping || mapping.platform !== asset.platform || mapping.arch !== asset.arch
      || (mapping.platform === 'linux' ? asset.libc !== mapping.libc : asset.libc !== undefined)) {
      throw policyError('manifest_target_mismatch', asset.target || asset.archive);
    }
    const expectedBinary = nativeProductBinaryName(asset.product);
    const expectedBinaryPath = nativeProductBinaryPath(asset.product, asset.platform);
    if (!expectedBinary || !expectedBinaryPath || asset.binary !== expectedBinary) {
      throw policyError('manifest_binary_product_mismatch', asset.binary);
    }

    const binaryPath = normalizeNativeArchivePath(asset.binary_path, 'file');
    if (binaryPath !== asset.binary_path || binaryPath.split('/').at(-1) !== expectedBinaryPath) {
      throw policyError('manifest_binary_basename_mismatch', asset.binary_path);
    }

    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;

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Check asset.product and asset.platform values are valid supported combinations
  2. Set asset.binary to exactly nativeProductBinaryName(asset.product) output
  3. Regenerate the manifest with the bundled generator instead of editing by hand
  4. If introducing a new product, update nativeProductBinaryName/nativeProductBinaryPath in policy.ts first

Example fix

// before
{ product: 'omxd', platform: 'linux-x64', binary: 'omx-daemon' }
// after
{ product: 'omxd', platform: 'linux-x64', binary: 'omxd' }
Defensive patterns

Strategy: validation

Validate before calling

import { nativeProductBinaryName, nativeProductBinaryPath } from './policy';
const ok = asset.binary === nativeProductBinaryName(asset.product)
  && !!nativeProductBinaryPath(asset.product, asset.platform);

Type guard

function isValidAssetBinary(a: NativeAsset): boolean {
  return a.binary === nativeProductBinaryName(a.product)
    && !!nativeProductBinaryPath(a.product, a.platform);
}

Try / catch

try { loadNativeReleaseManifest(m); } catch (e) { if (String(e).includes('manifest_binary_product_mismatch')) fixBinaryFields(m); else throw e; }

Prevention

When it happens

Trigger: Calling loadNativeReleaseManifest (or validateNativeReleaseManifest directly) with a manifest whose asset.binary differs from nativeProductBinaryName(asset.product), or where the product/platform combination has no known binary path.

Common situations: Manifest hand-edited or generated by a newer/older toolchain with renamed binaries (e.g. product renamed, platform added), or a typo in the asset's product or binary field.

Related errors


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