Yeachan-Heo/oh-my-codex · error · Error

[native-assets] cache publication verification failed: ${fin

Error message

[native-assets] cache publication verification failed: ${final.state}

What it means

After atomically renaming the binary and sidecar into place, inspectManagedNativeBinary did not report state 'verified' for the published path. Publication is verified end-to-end (existence, digest match vs sidecar); any other state means the final artifact failed its own post-publication inspection.

Source

Thrown at src/cli/native-assets.ts:658

    await revalidatePublicationPaths();
    if (platform !== 'win32') await chmod(tempBinary, 0o755);
    const binary = await readOpenedFile(tempBinary, true, true);
    const sidecar = `${binary.digest}\n`;
    const handle = await open(tempSidecar, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
    try { await handle.writeFile(sidecar, 'utf8'); } finally { await handle.close(); }
    if ((await readOpenedFile(tempSidecar, true, false, MAX_SIDECAR_BYTES)).text !== sidecar) throw new Error('[native-assets] temporary checksum verification failed');
    await revalidatePublicationPaths();
    await quarantineInvalid(destination);
    await revalidatePublicationPaths();
    await quarantineInvalid(sidecarPath(destination));
    await revalidatePublicationPaths();
    await rename(tempBinary, destination);
    await revalidatePublicationPaths();
    await rename(tempSidecar, sidecarPath(destination));
    await revalidatePublicationPaths();
    const final = await inspectManagedNativeBinary(destination, env);
    await revalidatePublicationPaths();
    if (final.state !== 'verified') throw new Error(`[native-assets] cache publication verification failed: ${final.state}`);
    return final.path;
  } catch (error) {
    primaryError = error;
    throw error;
  } finally {
    const cleanupFailures: string[] = [];
    try { await revalidatePublicationPaths(); } catch (error) {
      cleanupFailures.push(`revalidate publication paths: ${error instanceof Error ? error.message : String(error)}`);
    }
    for (const temporary of [tempBinary, tempSidecar]) {
      try { await rm(temporary, { force: true }); } catch (error) {
        cleanupFailures.push(`remove ${temporary}: ${error instanceof Error ? error.message : String(error)}`);
      }
    }
    const lockCleanup = await releaseCacheLock(lock);
    if (lockCleanup) cleanupFailures.push(`${lockCleanup.state}: publication lock was retained`);
    if (cleanupFailures.length > 0) {
      const evidence = `[native-assets] cleanup evidence: ${cleanupFailures.join('; ')}`;

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Stop concurrent cache writers/pruners, clear the specific cache entry, retry once.
  2. Add cache directory exclusions to antivirus/sync tooling.
  3. Serialize installs or pre-hydrate caches to avoid post-publication races.
Defensive patterns

Strategy: retry

Try / catch

try { await hydrateNativeBinary(); } catch (e) { if (/cache publication verification failed/.test(String(e))) { /* stop other cache writers, clear entry, retry once */ } throw e; }

Prevention

When it happens

Trigger: publishManagedNativeBinary when the post-rename inspection returns e.g. 'digest-mismatch', 'missing-sidecar', or 'stale' — caused by tampering, filesystem races, or an external process deleting/altering files immediately after publication.

Common situations: Concurrent cache pruning by another process; antivirus quarantining freshly written executables; multi-process installs racing on the same destination.

Related errors


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