{"record":{"id":"4a8a59dd07329d2b","repo":"Yeachan-Heo/oh-my-codex","slug":"api-failed-to-launch-native-binary-executable-n","errorCode":null,"errorMessage":"[api] failed to launch native binary: executable not found (${binaryPath})","messagePattern":"\\[api\\] failed to launch native binary: executable not found \\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/cli/api.ts","lineNumber":221,"sourceCode":"\nfunction isHelpRequest(args: readonly string[]): boolean {\n  if (args.length === 0) return true;\n  return args.includes('--help') || args.includes('-h');\n}\n\nexport async function apiCommand(args: string[]): Promise<void> {\n  if (isHelpRequest(args)) {\n    console.log(API_USAGE);\n    return;\n  }\n\n  const binaryPath = await resolveApiBinaryPathWithHydration();\n\n  const result = runApiBinary(binaryPath, args);\n  if (result.error) {\n    const errno = result.error as NodeJS.ErrnoException;\n    const kind = classifySpawnError(errno);\n    if (kind === 'missing') throw new Error(`[api] failed to launch native binary: executable not found (${binaryPath})`);\n    if (kind === 'blocked') throw new Error(`[api] failed to launch native binary: executable is blocked (${errno.code || 'blocked'})`);\n    throw new Error(`[api] failed to launch native binary: ${errno.message}`);\n  }\n\n  writeApiResultOutput(result);\n  if (result.status !== 0) {\n    process.exitCode = typeof result.status === 'number'\n      ? result.status\n      : resolveSignalExitCode(result.signal);\n  }\n}\n","sourceCodeStart":203,"sourceCodeEnd":233,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/cli/api.ts#L203-L233","documentation":"`omx api` resolved a binary path but spawning it failed with an error classified as 'missing' (typically ENOENT), meaning the file at binaryPath does not exist or is not executable at spawn time. The path existed during resolution but vanished or is inaccessible when passed to spawnSync/execFile.","triggerScenarios":"Calling `omx api ...` where the resolved path was deleted between resolution and spawn, is a dangling symlink, sits on an unmounted filesystem, or where the interpreter/loader referenced by the binary is absent.","commonSituations":"Race conditions where another process cleans node_modules or the cache mid-run; dangling symlinks in the managed cache; container filesystems mounted lazily; the binary present but its dynamic loader missing on minimal images.","solutions":["Re-run the command (transient deletion races usually clear) and reinstall/re-hydrate the binary if it persists","Verify the file actually exists and is not a broken symlink: `ls -l <binaryPath>`","Set OMX_API_BIN_ENV to a known-good binary location","Check that the target filesystem is mounted and accessible inside containers"],"exampleFix":"# before\nomx api status   # ENOENT at spawn\n# after\nls -l /path/to/omx-api   # confirm it exists\nomx api status","handlingStrategy":"retry","validationCode":"import { existsSync, statSync } from 'node:fs';\nconst ok = existsSync(binPath) && statSync(binPath).isFile();\nif (!ok) throw new Error(`binary missing before launch: ${binPath}`);","typeGuard":null,"tryCatchPattern":"catch (e) { if (/executable not found \\(\\S+omx-api/.test(String(e))) { await rehydrateBinary(); retry(); } else throw e; }","preventionTips":["Check file existence immediately before spawn","Avoid concurrent installs/upgrades while omx runs","Pin immutable binary locations in CI caches"],"tags":["spawn","enoent","native-binary","api","race-condition"],"backgroundTag":"spawn-enoent","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}