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

[api] native binary not found. Checked cached/native candida

Error message

[api] native binary not found. Checked cached/native candidates under ${packageRoot}, ${repoLocal}, and ${nestedRepoLocal}. ${rejectedCache ? `Rejected managed cache entry ${rejectedCache.path} (${rejectedCache.state}). ` : ''}Reconnect to the network so OMX can fetch the release asset, or set ${OMX_API_BIN_ENV} to override the path.

What it means

Like error 81 but thrown after hydration: `resolveApiBinaryPathWithHydration` first tries to download/fetch the native binary into a managed cache via `hydrateNativeBinary`, and only throws when that also fails (e.g. offline). The message distinguishes a rejected cache entry (stale/corrupt state) from simply having no candidates, and suggests reconnecting or setting the override env var.

Source

Thrown at src/cli/api.ts:177

    const inspected = await inspectManagedNativeBinary(cached, env);
    if (inspected.state === 'verified') return inspected.path!;
    if (inspected.state !== 'missing') rejectedCache ??= { path: cached, state: inspected.state };
  }

  for (const packaged of packagedApiBinaryCandidatePaths(packageRoot, platform, arch, env, linuxLibcPreference)) {
    if (exists(packaged)) return packaged;
  }

  const repoLocal = repoLocalApiBinaryPath(packageRoot, platform);
  if (exists(repoLocal)) return repoLocal;

  const nestedRepoLocal = nestedRepoLocalApiBinaryPath(packageRoot, platform);
  if (exists(nestedRepoLocal)) return nestedRepoLocal;

  const hydrated = await hydrateNativeBinary('omx-api', { packageRoot, env, platform, arch });
  if (hydrated) return hydrated;

  throw new Error(
    `[api] native binary not found. Checked cached/native candidates under ${packageRoot}, ${repoLocal}, and ${nestedRepoLocal}. `
      + `${rejectedCache ? `Rejected managed cache entry ${rejectedCache.path} (${rejectedCache.state}). ` : ''}`
      + `Reconnect to the network so OMX can fetch the release asset, or set ${OMX_API_BIN_ENV} to override the path.`,
  );
}

export function runApiBinary(
  binaryPath: string,
  args: readonly string[],
  options: RunApiBinaryOptions = {},
): SpawnSyncReturns<string> {
  const { cwd = process.cwd(), env = process.env, spawnImpl = spawnSync } = options;
  const spawnOptions: SpawnSyncOptionsWithStringEncoding = {
    cwd,
    env,
    stdio: ['ignore', 'pipe', 'pipe'],
    encoding: 'utf-8',
  };

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Reconnect to the network (or fix proxy/firewall rules) so the release asset can be fetched, then retry
  2. Set OMX_API_BIN_ENV to point at a manually provisioned omx-api binary
  3. Clear the rejected managed cache entry and retry so it is re-downloaded cleanly
  4. Pre-provision the binary in the image/cache so no network fetch is needed at runtime

Example fix

# before
omx api status   # offline, no binary
# after
export OMX_API_BIN=/opt/omx/bin/omx-api
omx api status
Defensive patterns

Strategy: fallback

Validate before calling

import { existsSync } from 'node:fs';
if (!process.env.OMX_API_BIN) {
  console.warn('No local omx-api binary; ensure network access for first-run hydration');
}

Try / catch

catch (e) { if (/Reconnect to the network/.test(String(e))) { switchToPinnedLocalBinary(); } else throw e; }

Prevention

When it happens

Trigger: Running `omx api` (or calling `binaryPath()`/`resolveApiBinaryPathWithHydration`) while offline with no local binary and no usable cached copy, or when the managed cache entry exists but is in a rejected state (failed verification/partial download).

Common situations: Air-gapped or proxied CI environments blocking the release asset download; expired or corrupt download cache; firewall blocking the GitHub/release host; laptops on restricted networks.

Related errors


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