# How to Debug Codex Plugin Issues and Common Errors: A Complete Guide

> Debug Codex plugin issues and common errors by inspecting on-disk job logs and state.json. Learn how to check error codes and verify your Codex CLI installation.

- Repository: [OpenAI/codex-plugin-cc](https://github.com/openai/codex-plugin-cc)
- Tags: how-to-guide
- Published: 2026-07-04

---

**The Codex plugin persists failure states directly to on-disk job logs and [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json), allowing you to debug most issues by inspecting the state directory, checking for normalized OS error codes like `ENOENT` or `ECONNREFUSED`, and verifying your Codex CLI installation.**

Debugging Codex plugin issues and common errors requires understanding how the openai/codex-plugin-cc repository handles background job execution and state persistence. The plugin acts as a thin wrapper around the locally installed Codex CLI, translating slash commands like `/codex:review` into persistent jobs that log their output to disk. When failures occur, the error details are written to per-job log files and the global state, making systematic log inspection the fastest path to resolution.

## Understanding the Plugin Architecture

The Codex plugin consists of six core components that handle command execution, state persistence, and error surfacing. Knowing which module owns each failure point helps you locate the exact source of an error.

### Command Dispatcher

The **command dispatcher** in `plugins/codex/scripts/lib/job-control.mjs` parses user slash commands and builds job descriptions. When you invoke `/codex:review` or `/codex:rescue`, this module creates the job descriptor and hands it off to the process runner.

### State Manager

The **state manager** in `plugins/codex/scripts/lib/state.mjs` creates a per-workspace directory (defaulting to `/tmp/codex-companion` or the path specified by `CLAUDE_PLUGIN_DATA`) and manages [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json) plus per-job files. It provides `resolveJobLogFile()` and `loadState()` to locate and read persisted data.

### Process Runner

The **process runner** in `plugins/codex/scripts/lib/process.mjs` spawns the Codex binary and captures stdout/stderr. It normalizes OS-level errors such as `ENOENT`, `ECONNREFUSED`, `ESRCH`, and `ETIMEDOUT` into detectable error codes.

### Codex Client

The **Codex client** in `plugins/codex/scripts/lib/codex.mjs` communicates via JSON-RPC with the app-server. It handles the `error?.rpcCode` checks, including the `BROKER_BUSY_RPC_CODE` branch for authentication failures and `-32601` for unsupported methods.

### Render Layer

The **render layer** in `plugins/codex/scripts/lib/render.mjs` formats job output for Claude Code and injects error messages into the UI via `errorMessage` fields.

### Lifecycle Hooks

**Hooks** such as `plugins/codex/scripts/stop-review-gate-hook.mjs` implement optional gates (like the stop-review gate) that can cancel jobs after timeouts.

## The Debugging Workflow

Follow this systematic approach to isolate the layer causing the failure:

1. **Verify Codex CLI availability** – Run `!codex login` in Claude Code or execute `codex version` from your terminal to confirm the binary is accessible.

2. **Check the job list** – Run `/codex:status` to print recent job IDs, states, and timestamps. This uses `listJobs()` from `state.mjs`.

3. **Inspect the job log** – Each job creates a `<job-id>.log` file in the state directory. Use `resolveJobLogFile(cwd, jobId)` from `plugins/codex/scripts/lib/state.mjs` to locate the exact path.

4. **Read the persisted state** – Open [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json) in the state directory to view global config (like `stopReviewGate`) and the ordered job list via `loadState()`.

5. **Search for known error codes** – Look for `ENOENT`, `ECONNREFUSED`, `ESRCH`, or `ETIMEDOUT` in the log files. The detection logic resides in `process.mjs`.

6. **Re-run with background flags** – Execute commands with `--background` or `--wait` to avoid UI deadlocks and capture logs while the job runs.

7. **Enable verbose logging** – Set `DEBUG=codex*` in your environment or add `"logLevel": "debug"` to `~/.codex/config.toml` and restart Claude Code.

8. **Consult the test suite** – Review `tests/process.test.mjs` and other unit tests to see expected error handling patterns.

## Common Failure Modes and Fixes

| Symptom | Root Cause | Fix |
|---------|------------|-----|
| **"Codex not installed"** | `process.mjs` throws `ENOENT` when the `codex` binary is missing. | Run `/codex:setup` or install manually: `npm install -g @openai/codex`. |
| **Authentication error** | `codex.mjs` detects `error?.rpcCode === BROKER_BUSY_RPC_CODE`. | Run `!codex login` again; verify your ChatGPT subscription or API key. |
| **Network/connection refused** | `process.mjs` detects `ECONNREFUSED` when the app-server is unreachable. | Ensure the app-server is running (`codex start`) and check firewall rules. |
| **Job timed out** | `stop-review-gate-hook.mjs` cancels after `ETIMEDOUT`. | Increase `reviewGateTimeout` in [`.codex/config.toml`](https://github.com/openai/codex-plugin-cc/blob/main/.codex/config.toml) (e.g., `"5m"`), or run the review manually. |
| **Unexpected JSON parsing error** | `app-server.mjs` fails to parse JSONL lines (`Failed to parse codex app-server JSONL`). | Inspect the offending line in the log; often caused by a corrupted binary—reinstall Codex. |
| **Maximum job limit exceeded** | `state.mjs` prunes jobs to `MAX_JOBS = 50`, removing older logs. | Increase `MAX_JOBS` in `state.mjs` (requires rebuild) or clean up jobs with `/codex:cancel`. |
| **"Unsupported method" errors** | Older CLI versions lack newer RPC methods like `externalAgentConfig/import`, returning JSON-RPC code `-32601` in `codex.mjs`. | Upgrade the CLI: `npm update -g @openai/codex`. |

## Practical Debugging Examples

### Inspecting a Failed Job

Use the same logic as `state.mjs` to locate and read job logs programmatically:

```javascript
// Get the job ID from `/codex:status`
const jobId = "job-1623-abc123";

// Resolve the log file path using state.mjs helpers
import { resolveJobLogFile } from "./plugins/codex/scripts/lib/state.mjs";
const logPath = resolveJobLogFile(process.cwd(), jobId);
console.log(`Log file → ${logPath}`);

// Read the log (Node.js)
import fs from "node:fs";
const log = fs.readFileSync(logPath, "utf8");
console.log("--- Job Log ---\n", log);

// Check for specific OS error codes
if (/ENOENT|ECONNREFUSED/.test(log)) {
  console.log("🔧 Binary missing or network issue detected—verify Codex installation.");
}

```

### Enabling Debug Logging

Run commands with verbose output to capture real-time RPC and process details:

```bash

# Enable debug output for the plugin

export DEBUG=codex*

# Run a review in the background to avoid UI blocking

/codex:review --background

# In another terminal, tail the latest job log

tail -f "$(codex status | grep -oE 'job-[0-9a-f]+' | head -n1)/$(codex status | grep -oE 'job-[0-9a-f]+' | head -n1).log"

```

## Key Source Files for Debugging

Keep these file paths handy when tracing errors through the codebase:

- **`plugins/codex/scripts/lib/state.mjs`** – State directory resolution, `resolveJobLogFile()`, `loadState()`, and job pruning logic.
- **`plugins/codex/scripts/lib/process.mjs`** – Spawns the Codex CLI and normalizes OS errors (`ENOENT`, `ESRCH`, `ETIMEDOUT`).
- **`plugins/codex/scripts/lib/codex.mjs`** – JSON-RPC client, error mapping (`BROKER_BUSY_RPC_CODE`, `-32601`), and retry logic.
- **`plugins/codex/scripts/lib/render.mjs`** – Formats job results and error messages for the Claude Code UI.
- **`plugins/codex/scripts/lib/job-control.mjs`** – Creates and updates job descriptors, handles cancellation.
- **`plugins/codex/scripts/stop-review-gate-hook.mjs`** – Implements the optional review gate that can timeout with `ETIMEDOUT`.
- **`tests/process.test.mjs`** – Unit tests documenting expected error paths for missing processes.

## Summary

- **Check [`state.json`](https://github.com/openai/codex-plugin-cc/blob/main/state.json)** in your state directory (default `/tmp/codex-companion`) to verify global configuration and the job list.
- **Inspect job logs** using `resolveJobLogFile()` from `state.mjs` to find detailed error output.
- **Verify CLI availability** with `!codex login` before running commands to avoid `ENOENT` errors.
- **Watch for normalized error codes** like `ENOENT`, `ECONNREFUSED`, `ESRCH`, and `ETIMEDOUT` in logs from `process.mjs`.
- **Enable `DEBUG=codex*`** for verbose RPC and process logging when standard logs are insufficient.
- **Upgrade the Codex CLI** when encountering `Unsupported method` (JSON-RPC `-32601`) errors.

## Frequently Asked Questions

### Where are Codex plugin logs stored?

The plugin stores logs in a per-workspace state directory that defaults to `/tmp/codex-companion`. You can override this location by setting the `CLAUDE_PLUGIN_DATA` environment variable. Each job writes to a `<job-id>.log` file located via the `resolveJobLogFile()` function in `plugins/codex/scripts/lib/state.mjs`.

### How do I fix "Codex not installed" errors?

This error appears when `process.mjs` detects an `ENOENT` error while attempting to spawn the `codex` binary. Resolve it by running `/codex:setup` from within Claude Code, or install the CLI manually by running `npm install -g @openai/codex` in your terminal. After installation, verify with `codex version`.

### Why do I get "Unsupported method" errors when running commands?

This occurs when the Codex client in `codex.mjs` receives JSON-RPC error code `-32601`, indicating your Codex CLI version lacks newer RPC methods like `externalAgentConfig/import`. Upgrade to the latest version by running `npm update -g @openai/codex` to resolve the mismatch.

### How do I enable debug logging for the Codex plugin?

Set the environment variable `DEBUG=codex*` before starting Claude Code, or add `"logLevel": "debug"` to your `~/.codex/config.toml` file. Verbose logging exposes JSON-RPC payloads, process spawn details, and state transitions, making it easier to trace failures through `codex.mjs` and `process.mjs`.