How to Cancel Running Codex Jobs: CLI Commands and Programmatic API

You can cancel running Codex jobs using the codex cancel <job-id> CLI command, the codex cancel --all batch flag, or programmatically via jobControl.cancel(jobId) in the JavaScript API, all of which gracefully terminate child processes and clean up tracked state.

The openai/codex-plugin-cc repository manages long-running analysis through a lightweight job-tracking system. Each job is registered in a central tracked-jobs map and coordinated by the job-control module, providing multiple interfaces to stop execution safely.

Methods to Cancel Running Codex Jobs

The plugin exposes three primary interfaces for cancellation, each targeting different workflows.

Cancel a Specific Job via CLI

Use the codex cancel command followed by the job identifier to stop a single running process.


# List active jobs to find the ID (optional)

codex status

# Cancel a specific job

codex cancel 12345

This command is documented in plugins/codex/commands/cancel.md. When executed, the CLI contacts the plugin’s internal broker, which forwards the request to jobControl.cancel(12345) and marks the job as cancelling before aborting pending work.

Cancel All Active Jobs

To stop every running job simultaneously, use the --all flag.

codex cancel --all

According to the source code in plugins/codex/commands/cancel.md, this flag iterates over the entire trackedJobs map and issues a cancel request for each entry, ensuring no orphaned processes remain.

Cancel Jobs Programmatically Using the API

For custom scripts or integrated workflows, import the jobControl module and call the cancel method directly.

import { jobControl } from '@codex/plugin';

// Assume you have the job ID from a previous request
const jobId = 'abcde-12345';

await jobControl.cancel(jobId);
console.log(`Job ${jobId} cancelled`);

This approach reaches the same cancellation logic used by the CLI, ensuring consistent behavior. The core implementation resides in plugins/codex/scripts/lib/job-control.mjs.

Handling Cancellation in Custom Workflows

You can check final state after cancellation using the state module.

import { state } from '@codex/plugin';
import { jobControl } from '@codex/plugin';

async function runAndPossiblyCancel() {
  const jobId = await startCodexJob(); // your own wrapper
  // ... some condition triggers a cancel
  await jobControl.cancel(jobId);
  const finalState = state.get(jobId);
  console.log(`Final state: ${finalState}`); // ⇒ "cancelled"
}

How Cancellation Works Under the Hood

The cancellation mechanism in openai/codex-plugin-cc is designed to be both graceful (allowing teardown) and idempotent (safe to call multiple times).

  1. Job registration – When a Codex request starts, the companion creates a Job object and stores it in the trackedJobs map (plugins/codex/scripts/lib/tracked-jobs.mjs).

  2. State tracking – The job’s status (running, completed, cancelling) is maintained in the central state module (plugins/codex/scripts/lib/state.mjs).

  3. Cancel request – The jobControl.cancel(jobId) function looks up the job in trackedJobs, sets its status to cancelling, and calls process.terminate() on any associated child processes via plugins/codex/scripts/lib/process.mjs.

  4. Cleanup – After the process stops, the job is removed from trackedJobs, the state is updated to cancelled, and temporary files are deleted by the filesystem utilities in fs.mjs.

Summary

  • Use codex cancel <job-id> to stop individual jobs from the command line.
  • Use codex cancel --all to batch-cancel every active job.
  • Call jobControl.cancel(jobId) programmatically for custom automation.
  • Key files include job-control.mjs for logic, tracked-jobs.mjs for the registry, and state.mjs for status tracking.
  • The process is graceful and idempotent, ensuring safe termination even if called multiple times.

Frequently Asked Questions

What happens if I cancel a job that has already completed?

The cancellation system is idempotent. If you call jobControl.cancel(jobId) on a job that is already completed or cancelled, the function returns immediately without error or side effects, as implemented in plugins/codex/scripts/lib/job-control.mjs.

Can I cancel Codex jobs from outside the CLI?

Yes. The jobControl API is exposed as part of the @codex/plugin package, allowing external Node.js scripts and automation tools to cancel jobs programmatically without invoking the CLI binary.

Is cancellation immediate or asynchronous?

Cancellation is asynchronous. When you invoke cancel(), the system marks the job as cancelling and terminates child processes, but cleanup operations (removing from trackedJobs, updating state, and deleting temporary files) complete asynchronously.

Where is the job state stored during the cancellation process?

Job state is stored in-memory in the trackedJobs Map within plugins/codex/scripts/lib/tracked-jobs.mjs, with status updates coordinated through plugins/codex/scripts/lib/state.mjs. This design ensures fast access but means job state is lost if the plugin process restarts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →