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

Unable to resolve OMX launcher path for exec

Error message

Unable to resolve OMX launcher path for exec

What it means

Thrown when the launcher cannot determine the absolute path to its own CLI entry script ('omx' bin) before spawning an exec-mode Codex child. The exec wrapper needs the launcher path to re-invoke OMX inside the child (e.g. for the runtime command shim), so an unresolvable path is fatal to exec delegation.

Source

Thrown at src/cli/index.ts:4255

        `[omx] preLaunch abort cleanup warning: ${cleanupErr instanceof Error ? cleanupErr.message : cleanupErr}`,
      );
    });
    throw err;
  }

  try {
    const notifyTempContractRaw = notifyTempResult.contract.active
      ? serializeNotifyTempContract(notifyTempResult.contract)
      : null;
    const codexArgs = injectModelInstructionsBypassArgs(
      cwd,
      ["exec", ...normalizedArgs],
      process.env,
      sessionModelInstructionsPath(cwd, sessionId),
    );
    const omxRootOverride = resolveOmxRootForLaunch(cwd, process.env);
    const omxBin = resolveOmxCliEntryPath({ argv1: process.argv[1], cwd, env: process.env });
    if (!omxBin) throw new Error("Unable to resolve OMX launcher path for exec");
    const hudRuntimeRoot = resolveHudRuntimeRootForLaunch(cwd, process.env);
    const codexEnvBase = prependOmxRuntimeCommandShimToEnv(
      cwd,
      {
        ...stripHermesMcpBridgeEnv(process.env),
        ...(codexHomeOverride ? { CODEX_HOME: codexHomeOverride } : {}),
        ...(sqliteHomeOverride ? { [CODEX_SQLITE_HOME_ENV]: sqliteHomeOverride } : {}),
        ...(omxRootOverride ? { OMX_ROOT: omxRootOverride } : {}),
      },
      omxBin,
    );
    // Correlates plugin hook routing only; it is not an authority token.
    const pluginHookRoutingLaunchId = randomUUID();
    const codexEnv = {
      ...codexEnvBase,
      OMX_CODEX_LAUNCH_ID: pluginHookRoutingLaunchId,
      ...buildHudRuntimeEnv({ sessionId, ...hudRuntimeRoot }).env,
      ...(notifyTempContractRaw ? { [OMX_NOTIFY_TEMP_CONTRACT_ENV]: notifyTempContractRaw } : {}),

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Reinstall OMX cleanly (npm i -g omx or via the documented installer) so the bin shim and entry file are consistent
  2. Run through the documented bin entry (the omx command) rather than importing internals or wrapping with custom loaders
  3. Check that process.argv[1] resolves to a real file on disk from your cwd; if wrapping, set argv/env so the entry path is discoverable
  4. Avoid running under bundlers or tsx/node loaders that rewrite argv without preserving the entry module

Example fix

// before
$ node -e "require('/opt/omx/dist/cli/index.js')('exec', ...)

// after
$ omx exec ... // use the installed bin so argv1 resolves the OMX entry
Defensive patterns

Strategy: validation

Validate before calling

import { resolveOmxCliEntryPath } from "omx";
const bin = resolveOmxCliEntryPath({ argv1: process.argv[1], cwd: process.cwd(), env: process.env });
if (!bin) { /* fall back to plain codex invocation or abort */ }

Try / catch

try { await omxExec(args); } catch (e) { if (e instanceof Error && /OMX launcher path/.test(e.message)) { /* reinstall or run via the omx bin */ } throw e; }

Prevention

When it happens

Trigger: resolveOmxCliEntryPath returns falsy when argv[1] does not point at a resolvable OMX entry file — running via a mechanism that rewrites argv (some wrappers, bundled binaries, eval-style loaders), a missing/moved node_modules/omx install, or a cwd/env combination where module resolution of the entry fails.

Common situations: Installing via unusual package managers that symlink oddly (pnpm shims, npx cache runs), running from a global install whose real path differs from argv1, running inside containers or bundlers where require.resolve of the entry fails, or partial/corrupted installs.

Related errors


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