thedotmack/claude-mem · error · Error

codex ${args.join(' ')} failed with exit code ${exitCode}${s

Error message

codex ${args.join(' ')} failed with exit code ${exitCode}${stderr ? `: ${stderr}` : ''}

What it means

runCodex() is the wrapper that spawns the `codex` CLI (resolved to codex.cmd on Windows). If the child process exits with a non-zero status (and did not fail to spawn), it throws an Error echoing the exact args, the exit code, and (when present) the trimmed stderr. This surfaces real codex failures such as marketplace add/remove conflicts that are not the recoverable 'already added from a different source' case.

Source

Thrown at src/services/integrations/CodexCliInstaller.ts:160

  const invocation = resolveCodexSpawnInvocation(args);
  return spawnSync(invocation.command, invocation.args, invocation.options);
}

function runCodex(args: string[]): void {
  const result = codexSpawn(args);
  const output = console;
  const stdout = result.stdout?.trimEnd();
  const stderr = result.stderr?.trimEnd();

  if (stdout) output.log(stdout);
  if (stderr) output.error(stderr);

  if (result.error) {
    throw result.error;
  }
  if (result.status !== 0) {
    const exitCode = result.status ?? 'unknown';
    throw new Error(`codex ${args.join(' ')} failed with exit code ${exitCode}${stderr ? `: ${stderr}` : ''}`);
  }
}

function isMarketplaceDifferentSourceError(error: unknown): boolean {
  const message = error instanceof Error ? error.message : String(error);
  return message.includes(`marketplace '${MARKETPLACE_NAME}' is already added from a different source`)
    || message.includes(`marketplace \`${MARKETPLACE_NAME}\` is already added from a different source`);
}

function registerCodexMarketplace(marketplaceRoot: string): void {
  try {
    runCodex(['plugin', 'marketplace', 'add', marketplaceRoot]);
    return;
  } catch (error) {
    if (!isMarketplaceDifferentSourceError(error)) {
      throw error instanceof Error ? error : new Error(String(error));
    }
  }

View on GitHub (pinned to d768ba3643)

Solutions

  1. Read the exit code and stderr in the message — they are the literal codex output, so fix the underlying codex error.
  2. If it is a permissions issue, check ownership/permissions of ~/.codex and its config files.
  3. Re-run the exact codex command shown in the args manually to reproduce and debug interactively.
  4. Update or reinstall the Codex CLI if the failure is a known bug in the installed version.
  5. Clear any stale codex locks/state and retry the install.

Example fix

# before — codex marketplace add fails
codex plugin marketplace add /path/to/root
# nonzero exit -> runCodex throws

# after — run manually to see full stderr, fix root cause, retry
codex plugin marketplace add /path/to/root
chmod -R u+w ~/.codex   # if permissions
npx claude-mem@latest install --codex
Defensive patterns

Strategy: try-catch

Validate before calling

import { commandExists } from './codex-utils.js';
// Pre-flight: confirm codex is on PATH before invoking runCodex.
function ensureCodexAvailable(): void {
  if (!commandExists('codex') && process.platform !== 'win32') {
    throw new Error('codex CLI not found on PATH');
  }
}

Type guard

function isCodexRunFailure(e: unknown): boolean {
  return e instanceof Error && /codex .* failed with exit code/i.test(e.message);
}

Try / catch

try {
  runCodex(['plugin', 'marketplace', 'add', marketplaceRoot]);
} catch (e) {
  if (isMarketplaceDifferentSourceError(e)) {
    runCodex(['plugin', 'marketplace', 'remove', MARKETPLACE_NAME]);
    runCodex(['plugin', 'marketplace', 'add', marketplaceRoot]);
    return;
  }
  // Real failure — echo args + stderr for the operator.
  throw e;
}

Prevention

When it happens

Trigger: Any codex subcommand run by the installer exits non-zero: `codex plugin marketplace add`/`remove` fails for a reason other than the recognized different-source conflict; a codex config write command errors; codex itself crashes or hits a permission error. The recognized different-source conflict is filtered out earlier in registerCodexMarketplace and does NOT reach this throw.

Common situations: Codex config dir ~/.codex is read-only or owned by another user; codex version behaves differently than expected for a subcommand; the marketplace path passed to `add` is unreachable; a stale lock in ~/.codex; codex hit an internal panic and wrote it to stderr.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/1443b7567b72dc81. Report an issue: GitHub.