openai / openai/codex-plugin-cc
Background jobs: prompt text swallowed as options (-m pytest -> model 404); dead workers never finalized; cancel hangs; stderr discarded
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 33.3k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Four defects found while diagnosing reliability issues with background jobs on Windows. All verified against plugin source v1.0.6 with session logs and on-disk job state. Environment: Windows 11, plugin 1.0.6, codex CLI 0.148.0 / 0.150.1.
1. Natural-language prompt words are swallowed as CLI options (-m pytest → model pytest)
When a caller passes a task as a single raw argument string, splitRawArgumentString (scripts/lib/args.mjs:76-127) tokenizes it shell-style, and parseArgs then interprets -m via aliasMap: { m: "model" } (codex-companion.mjs:764-768). A prompt containing python -m pytest tests parses to options.model = "pytest", which normalizeRequestedModel (codex-companion.mjs:103-111) passes through unchanged, producing gateway 404s:
Model "pytest" is not supported
Reproduced 3× (rollout turn_context with model="pytest" at 3 timestamps; corresponding job logs show the 404s). This is version-independent (parsing happens in the plugin).
Suggested fix: don't shell-split structured input; pass prompts as a dedicated field or require -- separation; drop or rename the m alias; validate model values against the known catalog before sending.
Workaround: avoid bare -m in prompt text, or use --prompt-file.
2. Dead background workers are never finalized (zombie running jobs)
Background jobs spawn detached workers with stdio: "ignore" + child.unref() (codex-companion.mjs:671-682), and job state is written after spawn (684-698). If the worker dies at any point, nothing marks the job failed — tracked-jobs.mjs:142-203 only finalizes on normal runner return/throw, and there is no watchdog, PID liveness check, or timeout reclaim (job-control.mjs:281-307 treats queued/running as active indefinitely).
On-disk evidence: jobs created days apart still running with dead PIDs; one from Aug 21 whose log contains only Starting Codex Resume.. Two jobs from different workspaces/brokers stopped at the same second (network-level kill event) and both remain running forever.
Suggested fix: worker heartbeat or PID liveness checks; queued/running timeout reclaim; write a terminal state whenever the worker process is observed dead.
3. cancel hangs because it awaits an interrupt with no timeout
handleCancel awaits interruptAppServerTurn before killing the process tree (codex-companion.mjs:963-987), with no timeout wrapper (codex.mjs:960-992). If the broker/turn is already gone, the await blocks indefinitely; terminateProcessTree and the status write never execute. Corroborating evidence: the entire job-state directory contains zero cancelled records despite explicit user cancels. Minor secondary issue: terminateProcessTree(job.pid ?? NaN) when pid is absent.
Suggested fix: short timeout on interrupt → force-kill process tree on expiry → always write a terminal state; skip the interrupt path entirely for jobs whose PID is already dead.
4. All worker stderr is discarded (zero observability)
stdio: "ignore" means codex CLI / app-server stderr (connection drops, retry storms, panics) is never persisted. This made root-causing #2 impossible from local evidence — the actual death cause of the same-second worker deaths could not be determined because all evidence was destroyed by design.
Suggested fix: persist worker stdout/stderr to the job log (even best-effort tail), at least around spawn/connect/turn lifecycle transitions.
Workarounds in use
Foreground mode for critical tasks; avoid bare -m in prompts; periodic cleanup of zombie job files and orphaned cxc-* temp dirs.
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 by tracing scripts/lib/args.mjs:76-127 and codex-companion.mjs:764-768 for raw prompt parsing, then inspect the worker lifecycle in codex-companion.mjs:671-698, tracked-jobs.mjs:142-203, and job-control.mjs:281-307. Review cancellation in codex-companion.mjs:963-987 and codex.mjs:960-992. Done means prompts no longer corrupt model selection, dead or cancelled jobs reach terminal states, and worker stderr is retained in job logs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- backend, cli, observability
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100