{"record":{"id":"3e0dc7f4db89ab76","repo":"nexu-io/open-design","slug":"codex-mcp-remove-failed-failuredetail-result","errorCode":null,"errorMessage":"codex mcp remove failed: ${failureDetail(result)}","messagePattern":"codex mcp remove failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/codex-cli.ts","lineNumber":115,"sourceCode":"  env: Record<string, string>;\n}\n\nexport async function installCodexMcp(spec: CodexInstallSpec): Promise<void> {\n  const argv: string[] = ['mcp', 'add', spec.name];\n  for (const [key, value] of Object.entries(spec.env)) {\n    argv.push('--env', `${key}=${value}`);\n  }\n  argv.push('--', spec.command, ...spec.args);\n  const result = await activeRunner().run(argv);\n  if (result.exitCode !== 0) {\n    throw new Error(`codex mcp add failed: ${failureDetail(result)}`);\n  }\n}\n\nexport async function uninstallCodexMcp(name: string): Promise<void> {\n  const result = await activeRunner().run(['mcp', 'remove', name]);\n  if (result.exitCode !== 0) {\n    throw new Error(`codex mcp remove failed: ${failureDetail(result)}`);\n  }\n}\n\nfunction failureDetail(result: CodexRunnerResult): string {\n  return result.stderr.trim() || result.stdout.trim() || `exit ${result.exitCode}`;\n}\n","sourceCodeStart":97,"sourceCodeEnd":122,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/codex-cli.ts#L97-L122","documentation":"Thrown by uninstallCodexMcp after `codex mcp remove <name>` exits non-zero. As with add, failureDetail surfaces stderr/stdout/exit code from the Codex CLI. This path is the 'uninstall' side of the Settings one-click Codex MCP toggle.","triggerScenarios":"Clicking uninstall when no server with that name is registered in ~/.codex/config.toml, when config.toml is corrupt or unwritable, or when the Codex CLI itself errors during removal.","commonSituations":"Stale toggle state (UI thinks it is installed but it was already removed manually), a hand-edited config.toml that breaks Codex's parser, or a Codex CLI version that changed the remove subcommand.","solutions":["Inspect the appended failureDetail for Codex's own error text.","Run `codex mcp get <name>`; if it is already gone, treat the uninstall as already-complete.","Open ~/.codex/config.toml and remove the entry by hand if the CLI refuses.","Upgrade or reinstall the Codex CLI if the remove subcommand is malfunctioning."],"exampleFix":"// before: remove fails because entry is absent\ncodex mcp remove open-design\n// after: verify it is gone, then no-op\ncodex mcp get open-design   # not-found -> already uninstalled","handlingStrategy":"try-catch","validationCode":"// Treat 'not installed' as success to avoid the remove failure.\nconst status = await probeCodexInstall(name);\nif (!status.installed) return; // nothing to remove\nawait uninstallCodexMcp(name);","typeGuard":null,"tryCatchPattern":"try {\n  await uninstallCodexMcp(name);\n} catch (err) {\n  const detail = err instanceof Error ? err.message : String(err);\n  if (/not found|no such|remove failed/i.test(detail)) {\n    return; // already gone — desired state reached\n  }\n  throw err;\n}","preventionTips":["Probe before removing so an already-clean state is a no-op.","Keep the toggle state in sync with probeCodexInstall rather than a local cached flag.","If config.toml is hand-edited, validate it parses before relying on the CLI."],"tags":["codex","mcp","cli","integration","spawn"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}