Yeachan-Heo/oh-my-codex · error
manifest_duplicate_archive_basename
manifest_duplicate_archive_basename
Error message
[native-assets] manifest_duplicate_archive_basename: ${basename} What it means
Two different logical assets share the same archive basename, which would collide on disk when downloading or extracting. The validator tracks every basename and rejects repeats.
Source
Thrown at src/native-assets/policy.ts:177
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;
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
- Give each asset a unique archive basename encoding its target
- Re-check for accidental duplicate rows
- Regenerate names from the asset fields so they cannot collide
Example fix
// before
[..., {archive:'omxd-linux-x64.tar.zst'}, {archive:'omxd-linux-x64.tar.zst'}]
// after
[..., {archive:'omxd-linux-x64.tar.zst'}, {archive:'omxd-linux-arm64.tar.zst'}] Defensive patterns
Strategy: validation
Validate before calling
const names = new Set<string>();
const ok = assets.every((a) => { const b = nativeReleaseAssetBasename(a); if (names.has(b)) return false; names.add(b); return true; }); Prevention
- Derive archive names from asset fields so collisions are impossible
When it happens
Trigger: Two entries with different logical keys but the identical archive filename, e.g. both ending in 'omxd-linux-x64.tar.zst'.
Common situations: Copy-paste when adding an asset without updating the filename, or a generator bug emitting the same name for multiple targets.
Related errors
- [native-assets] failed to fetch native release manifest (${r
- [native-assets] manifest version mismatch: expected ${versio
- manifest_binary_product_mismatch
- manifest_binary_basename_mismatch
- manifest_duplicate_logical_key
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/1f3f0a8c192faf29.
Report an issue: GitHub.