{"record":{"id":"1443b7567b72dc81","repo":"thedotmack/claude-mem","slug":"codex-args-join-failed-with-exit-code-ex","errorCode":null,"errorMessage":"codex ${args.join(' ')} failed with exit code ${exitCode}${stderr ? `: ${stderr}` : ''}","messagePattern":"codex (.+?) failed with exit code (.+?)(.+?)` : ''\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/integrations/CodexCliInstaller.ts","lineNumber":209,"sourceCode":"  const invocation = resolveCodexSpawnInvocation(args);\n  return spawnSync(invocation.command, invocation.args, invocation.options);\n}\n\nfunction runCodex(args: string[]): void {\n  const result = codexSpawn(args);\n  const output = console;\n  const stdout = result.stdout?.trimEnd();\n  const stderr = result.stderr?.trimEnd();\n\n  if (stdout) output.log(stdout);\n  if (stderr) output.error(stderr);\n\n  if (result.error) {\n    throw result.error;\n  }\n  if (result.status !== 0) {\n    const exitCode = result.status ?? 'unknown';\n    throw new Error(`codex ${args.join(' ')} failed with exit code ${exitCode}${stderr ? `: ${stderr}` : ''}`);\n  }\n}\n\nfunction isMarketplaceDifferentSourceError(error: unknown): boolean {\n  const message = error instanceof Error ? error.message : String(error);\n  return message.includes(`marketplace '${MARKETPLACE_NAME}' is already added from a different source`)\n    || message.includes(`marketplace \\`${MARKETPLACE_NAME}\\` is already added from a different source`);\n}\n\nfunction registerCodexMarketplace(marketplaceRoot: string): void {\n  try {\n    runCodex(['plugin', 'marketplace', 'add', marketplaceRoot]);\n    return;\n  } catch (error) {\n    if (!isMarketplaceDifferentSourceError(error)) {\n      throw error instanceof Error ? error : new Error(String(error));\n    }\n  }","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/integrations/CodexCliInstaller.ts#L191-L227","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Read the stderr appended to the message and fix the underlying Codex CLI complaint (e.g. remove the conflicting marketplace first, then re-register).","If the marketplace is 'already added from a different source', run codex marketplace remove <name> (or the matching remove command) and retry the install.","Update the Codex CLI to a current version and rerun: npx claude-mem@latest install.","Retry after resolving transient network/auth issues surfaced in stderr."],"exampleFix":"// before: re-adding while an old source is registered\ncodex marketplace add claude-mem /old/path\n// Error: codex marketplace add claude-mem failed with exit code 1: marketplace 'claude-mem' is already added from a different source\n\n// after: remove the stale registration first\ncodex marketplace remove claude-mem\ncodex marketplace add claude-mem /new/path","handlingStrategy":"try-catch","validationCode":"import { execFileSync } from 'child_process';\ntry {\n  execFileSync('codex', ['--version'], { stdio: 'pipe' });\n} catch {\n  throw new Error('Codex CLI not available or failing; fix codex before installing');\n}","typeGuard":null,"tryCatchPattern":"try {\n  performCodexInstall();\n} catch (err) {\n  if (err instanceof Error && /codex .* failed with exit code/.test(err.message)) {\n    if (err.message.includes('already added from a different source')) {\n      // remove stale marketplace registration and retry\n    } else {\n      console.error('Codex CLI stderr:', err.message);\n    }\n  } else throw err;\n}","preventionTips":["Check `codex --version` and CLI health before running install/uninstall flows.","Handle the 'already added from a different source' case by removing the marketplace first.","Capture and log stderr from Codex commands for diagnosis.","Keep the Codex CLI updated so subcommand syntax matches."],"tags":["codex","cli","subprocess","exit-code"],"backgroundTag":"cli-command-failed","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}