{"record":{"id":"3431107d24eb0c82","repo":"Yeachan-Heo/oh-my-codex","slug":"native-agent-canonical-invalid","errorCode":"native_agent_canonical_invalid","errorMessage":"native_agent_canonical_invalid\nagent=${agent.name}\nmessage=alias/merged native agents must declare a canonical target","messagePattern":"native_agent_canonical_invalid\nagent=(.+?)\nmessage=alias/merged native agents must declare a canonical target","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/agents/policy.ts","lineNumber":69,"sourceCode":"  promptName: string,\n  manifest: Pick<CatalogManifest, \"agents\">,\n): boolean {\n  return (\n    manifest.agents.some((agent) => agent.name === promptName) ||\n    NON_NATIVE_AGENT_PROMPT_ASSETS.has(promptName)\n  );\n}\n\nexport function assertNativeAgentCanonicalTargets(\n  manifest: Pick<CatalogManifest, \"agents\">,\n): void {\n  const byName = getCatalogAgentByName(manifest);\n\n  for (const agent of manifest.agents) {\n    if (agent.status !== \"alias\" && agent.status !== \"merged\") continue;\n\n    if (!agent.canonical) {\n      throw new Error(\n        [\n          \"native_agent_canonical_invalid\",\n          `agent=${agent.name}`,\n          \"message=alias/merged native agents must declare a canonical target\",\n        ].join(\"\\n\"),\n      );\n    }\n\n    const canonical = byName.get(agent.canonical);\n    if (!canonical) {\n      throw new Error(\n        [\n          \"native_agent_canonical_invalid\",\n          `agent=${agent.name}`,\n          `canonical=${agent.canonical}`,\n          \"message=canonical native agent target is not listed in the catalog\",\n        ].join(\"\\n\"),\n      );","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/agents/policy.ts#L51-L87","documentation":"Thrown when the member entry to write exists but reports size zero, so the library refuses to hydrate it. An empty binary written to disk would create a broken executable, so validation happens before any file I/O.","triggerScenarios":"writeSelectedNativeArchiveMember found the entry but selected.size <= 0 at the pre-write check. Same root causes as other empty-entry errors: truncated archive, placeholder file, or corrupt size header.","commonSituations":"Disk-full during CI artifact packaging producing empty entries; partially-synced mirrors or caches; LFS pointers not fetched; antivirus/quarantine tools zeroing out binaries inside archives on shared storage.","solutions":["Re-download the archive and verify checksum/size against the release metadata","Confirm with unzip -l / tar -tvf that the entry size is non-zero; if not, the upstream asset is broken — rebuild it","Clear any intermediary cache (npm cache, CI cache, mirror) that may hold the truncated copy","Audit the release pipeline so binaries are fully built before archiving"],"exampleFix":"// before\nawait writeSelectedNativeArchiveMember(archive, 'mytool', dest); // throws archive_binary_empty\n\n// after\nconst entries = await inspectNativeArchive(archive);\nconst e = entries.find(c => c.normalizedName === 'mytool');\nif (!e || e.size <= 0) await refetchArchive();\nawait writeSelectedNativeArchiveMember(archive, 'mytool', dest);","handlingStrategy":"validation","validationCode":"const entries = await inspectNativeArchive(archivePath);\nconst e = entries.find(c => c.type === 'file' && c.normalizedName === member);\nif (!e || e.size <= 0) throw new Error('refusing to hydrate empty binary member');","typeGuard":"const isHydratable = (e: { type: string; size: number }): boolean => e.type === 'file' && e.size > 0;","tryCatchPattern":"try { await writeSelectedNativeArchiveMember(p, m, d); } catch (e) { if ((e as {code?:string}).code === 'archive_binary_empty') { await rm(p, {force:true}); /* re-fetch asset, retry once */ } else throw e; }","preventionTips":["Pre-check entry size before writing to disk","Verify checksums after download","Bust caches when a zero-byte entry is detected"],"tags":["native-assets","archive","corruption","hydration"],"backgroundTag":"corrupted-archive-file","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}