Failed Codex runs can leave temporary output directories behind
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.2k
- Forks
- 170
- PR merge metrics
- No merged PRs in 30d
Description
Summary
When codex-action invokes codex exec without an explicit output-file, the bundled helper creates a temporary directory for --output-last-message. That temporary output is cleaned only from the successful finalization path.
If the Codex process exits non-zero, the promise rejects before finalizeExecution() runs, so cleanupTempOutput() is never called and the temporary directory remains on the runner.
Root cause
runCodexExec creates an implicit output file before spawning Codex:
if (explicitOutputFile != null) {
outputFile = { type: "explicit", file: explicitOutputFile };
} else {
outputFile = await createTempOutputFile({ runAsUser });
}
Cleanup currently happens inside finalizeExecution:
try {
// read final message
} finally {
await cleanupTempOutput(outputFile, runAsUser);
}
but finalizeExecution is only called when the child exits with code 0:
if (code !== 0) {
reject(new Error(`${program} exited with code ${code}`));
return;
}
await finalizeExecution(outputFile, runAsUser);
The outer finally only cleans the output schema, not the temporary output file.
Expected behavior
Action-owned temporary output should be removed regardless of whether codex exec succeeds or fails. User-specified output-file paths should remain untouched.
Suggested fix
At the composite-action boundary, prepare an explicit action-owned output file when the user did not supply one, pass it through the existing --output-file option, and add an always() cleanup step.
That avoids changing the bundled helper while covering both success and failure paths. The preparation/cleanup logic should preserve unprivileged-user ownership by creating/removing its temporary directory through sudo -u <codex-user> / sudo rm as appropriate.
Impact
This is runner hygiene and reliability. Repeated failed Codex invocations can accumulate abandoned temporary directories, which is especially undesirable on long-lived self-hosted runners.
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 at the composite-action boundary and trace the runCodexExec, finalizeExecution, and cleanupTempOutput paths described in the issue. Prepare action-owned output only when output-file is absent, preserve unprivileged-user ownership, and verify with failure and success runs that action-owned directories are removed while user-specified paths remain untouched.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, typescript
- Domain
- ci-cd, devops
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100