openai / openai/codex-plugin-cc
task --background: detached worker is spawned before its job file is written, and a fast-failing worker leaves a permanently queued job that was reported as started
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 33.3k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
Version: plugin 1.0.6 (codex-companion.mjs), observed on Windows 11, Node 24, codex-cli 0.146.0-alpha.3.1.
Summary. enqueueBackgroundTask spawns the detached task worker before writing the job record the worker requires at startup. If the worker wins the race (or dies at startup for any reason), the parent still writes a queued record and reports the task as started. Nothing ever moves that record to a terminal state, and status reports it as active indefinitely.
Where (scripts/codex-companion.mjs, v1.0.6):
enqueueBackgroundTaskcallsspawnDetachedTaskWorker(cwd, job.id)at line 688, then writes the job file withwriteJobFile(...)at line 697 and upserts the index at line 698.- The worker (
handleTaskWorker, line 838) immediately reads that job file and throws if it is absent. - The worker is spawned with
stdio: "ignore"anddetached: true(lines 673-679), so its startup failure is invisible to the parent and to the user. renderQueuedTaskLaunch(line 556) then reports the task as started in the background.statusclassifies jobs from the storedstatusfield only (buildStatusSnapshot, lib/job-control.mjs line 213 onward); there is no PID liveness check, so the stuckqueuedrecord looks active forever.
Impact. A user who dispatches a background task gets a success message and a job id, but no work is running and no error ever surfaces. The failure mode is indistinguishable from a slow queue until the user inspects the log file (which contains only the "Queued for background execution." line).
Suggested fix. Write the job file and upsert the index BEFORE spawning the worker (swap lines 688-698 so writeJobFile/upsertJob precede spawnDetachedTaskWorker). The worker's read-at-startup then cannot race the write. Optionally: have status reconcile queued/running records whose pid is no longer alive.
Related hardening idea (separate, smaller). A cancel failure on Windows (taskkill returning an unrecognized nonzero, e.g. "operation not supported" under a restricted shell) throws in terminateProcessTree (lib/process.mjs line 97) before any cancellation bookkeeping, which also leaves the record active with no recovery path; a liveness reconciliation in status would cover both cases.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in scripts/codex-companion.mjs at enqueueBackgroundTask, comparing the ordering of writeJobFile, upsertJob, and spawnDetachedTaskWorker with handleTaskWorker's startup read. Verify that the job record is written and indexed before the worker starts, and that a dispatched task no longer remains permanently queued when the worker begins.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100