{"record":{"id":"c2e31e050a55b22a","repo":"Yeachan-Heo/oh-my-codex","slug":"manifest-duplicate-logical-key","errorCode":"manifest_duplicate_logical_key","errorMessage":"[native-assets] manifest_duplicate_logical_key: ${asset.archive}","messagePattern":"\\[native-assets\\] manifest_duplicate_logical_key: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/native-assets/policy.ts","lineNumber":170,"sourceCode":"    }\n    const mapping = nativeTargetMapping(asset.target);\n    if (!mapping || mapping.platform !== asset.platform || mapping.arch !== asset.arch\n      || (mapping.platform === 'linux' ? asset.libc !== mapping.libc : asset.libc !== undefined)) {\n      throw policyError('manifest_target_mismatch', asset.target || asset.archive);\n    }\n    const expectedBinary = nativeProductBinaryName(asset.product);\n    const expectedBinaryPath = nativeProductBinaryPath(asset.product, asset.platform);\n    if (!expectedBinary || !expectedBinaryPath || asset.binary !== expectedBinary) {\n      throw policyError('manifest_binary_product_mismatch', asset.binary);\n    }\n\n    const binaryPath = normalizeNativeArchivePath(asset.binary_path, 'file');\n    if (binaryPath !== asset.binary_path || binaryPath.split('/').at(-1) !== expectedBinaryPath) {\n      throw policyError('manifest_binary_basename_mismatch', asset.binary_path);\n    }\n\n    const key = nativeReleaseAssetLogicalKey(asset);\n    if (logicalKeys.has(key)) throw policyError('manifest_duplicate_logical_key', asset.archive);\n    logicalKeys.add(key);\n    const basename = nativeReleaseAssetBasename(asset);\n    if (asset.archive !== basename || !nativeArchiveSuffix(basename)) {\n      throw policyError('manifest_archive_invalid', asset.archive);\n    }\n    if (archiveHintMismatch(asset, basename)) throw policyError('manifest_archive_hint_mismatch', basename);\n    if (basenames.has(basename)) throw policyError('manifest_duplicate_archive_basename', basename);\n    basenames.add(basename);\n    let downloadUrl: URL;\n    try {\n      downloadUrl = new URL(asset.download_url);\n    } catch {\n      throw policyError('manifest_invalid_url', asset.download_url);\n    }\n    if ((downloadUrl.protocol !== 'https:' && downloadUrl.protocol !== 'http:')\n      || downloadUrl.pathname.split('/').at(-1) !== basename) {\n      throw policyError('manifest_url_basename_mismatch', asset.download_url);\n    }","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/native-assets/policy.ts#L152-L188","documentation":"Two assets in the manifest map to the same logical key (product/platform/target identity), meaning the same logical asset is declared twice. The validator enforces uniqueness via nativeReleaseAssetLogicalKey.","triggerScenarios":"Two entries with identical product+platform (or whatever fields compose the logical key), e.g. the same linux-x64 asset listed with two different archive names.","commonSituations":"Copy-pasted asset blocks when adding a new platform, or a partial edit that duplicated an existing row.","solutions":["Remove the duplicate entry so each logical asset appears once","If you need multiple archives per platform, restructure to distinct product/target values","Diff the manifest against the last known-good version to spot the copied block"],"exampleFix":"// before\n[{platform:'linux-x64',archive:'a.tar.zst'},{platform:'linux-x64',archive:'b.tar.zst'}]\n// after\n[{platform:'linux-x64',archive:'a.tar.zst'},{platform:'linux-arm64',archive:'b.tar.zst'}]","handlingStrategy":"validation","validationCode":"const keys = new Set<string>();\nfor (const a of manifest.assets) {\n  const k = nativeReleaseAssetLogicalKey(a);\n  if (keys.has(k)) throw new Error(`duplicate logical key: ${k}`);\n  keys.add(k);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Diff manifests before shipping","Automate manifest generation"],"tags":["native-assets","manifest","duplicate-key"],"backgroundTag":"manifest-validation-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}