Yeachan-Heo/oh-my-codex · error

[sparkshell] native binary not found. Checked cached/native

Error message

[sparkshell] 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_SPARKSHELL_BIN_ENV} to override the path.

What it means

Same as the sync resolver but in the hydrating path: no cached/native binary found, and the on-demand network hydration (hydrateNativeBinary) also failed — possibly because a managed cache entry existed but was rejected (state/path reported). Fix by getting network access for the release-asset download or pointing the env var at a binary.

Source

Thrown at src/cli/sparkshell.ts:183

    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 packagedSparkShellBinaryCandidatePaths(packageRoot, platform, arch, env, linuxLibcPreference)) {
    if (exists(packaged)) return packaged;
  }

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

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

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

  throw new Error(
    `[sparkshell] 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_SPARKSHELL_BIN_ENV} to override the path.`,
  );
}

export function runSparkShellBinary(
  binaryPath: string,
  args: readonly string[],
  options: RunSparkShellBinaryOptions = {},
): SpawnSyncReturns<string> {
  const {
    cwd = process.cwd(),
    env = process.env,
    spawnImpl = spawnSync,
  } = options;

  const configEnvOverrides = readConfiguredEnvOverrides(env.CODEX_HOME);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Reconnect to the network (or fix proxy/firewall) so OMX can fetch the release asset, then retry
  2. If a cache entry was rejected, clear the managed cache directory so it re-downloads cleanly
  3. Set OMX_SPARKSHELL_BIN to a locally available binary to bypass download entirely

Example fix

# before
omx sparkshell --json -- npm test
# after
OMX_SPARKSHELL_BIN=./bin/omx-sparkshell omx sparkshell --json -- npm test
Defensive patterns

Strategy: retry

Validate before calling

import { existsSync } from 'node:fs';
if (!existsSync(localCandidate) && !navigatorOnLine) { /* pre-download binary or set OMX_SPARKSHELL_BIN */ }

Try / catch

catch (e) { if (String(e).includes('Reconnect to the network')) { await retryWithBackoff(run); /* or set OMX_SPARKSHELL_BIN */ } else throw e; }

Prevention

When it happens

Trigger: resolveSparkShellBinaryPathWithHydration: all local candidates missing, hydrateNativeBinary returns falsy (offline, download failure), and optionally a cache entry was rejected (checksum/integrity state).

Common situations: Offline machine or proxy blocking GitHub release downloads, corrupted cache entry rejected by integrity checks, CI environments without network, or the platform package not shipped.

Related errors


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