thedotmack/claude-mem · error

codex failed with exit code ` : ''}

Error message

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

What it means

runCodex() shells out to the Codex CLI with execFileSync and treats any non-zero exit status as fatal. It throws an error embedding the full argument list, the exit code, and stderr, so callers (registerCodexMarketplace, performCodexInstall, uninstallCodexCli) fail loudly with the CLI's own diagnostic output attached.

Solutions

  1. Read the stderr appended to the message and fix the underlying Codex CLI complaint (e.g. remove the conflicting marketplace first, then re-register).
  2. If the marketplace is 'already added from a different source', run codex marketplace remove <name> (or the matching remove command) and retry the install.
  3. Update the Codex CLI to a current version and rerun: npx claude-mem@latest install.
  4. Retry after resolving transient network/auth issues surfaced in stderr.

Example fix

// before: re-adding while an old source is registered
codex marketplace add claude-mem /old/path
// Error: codex marketplace add claude-mem failed with exit code 1: marketplace 'claude-mem' is already added from a different source

// after: remove the stale registration first
codex marketplace remove claude-mem
codex marketplace add claude-mem /new/path
Defensive patterns

Strategy: try-catch

Validate before calling

import { execFileSync } from 'child_process';
try {
  execFileSync('codex', ['--version'], { stdio: 'pipe' });
} catch {
  throw new Error('Codex CLI not available or failing; fix codex before installing');
}

Try / catch

try {
  performCodexInstall();
} catch (err) {
  if (err instanceof Error && /codex .* failed with exit code/.test(err.message)) {
    if (err.message.includes('already added from a different source')) {
      // remove stale marketplace registration and retry
    } else {
      console.error('Codex CLI stderr:', err.message);
    }
  } else throw err;
}

Prevention

When it happens

Trigger: Any codex subcommand invocation (e.g. codex marketplace add/remove, codex plugin install/uninstall) exits non-zero — the CLI rejected the arguments, the marketplace is already added from a different source, network/auth failures, or the CLI itself errored and wrote to stderr.

Common situations: Marketplace already registered under a different path/source; Codex CLI version drift changed subcommand syntax; no network or auth for marketplace fetch; uninstalling a plugin that was never installed (exit 1).

Related errors


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

Appendix: source

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

  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 d8bc9755e7)