openai / openai/codex-plugin-cc

A server-side turn failure that terminates stores no `errorMessage`, so `status` reports the reason as `Summary: {`

Open
#757 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
33.3k
Forks
2.3k
PR merge metrics
No merged PRs in 30d

Description

Summary

A task turn that fails server-side and terminates normally leaves no reason anywhere in
status. The job is correctly marked failed, but the only diagnostic the report carries is

Summary: {

— a bare opening brace: the first line of the pretty-printed JSON error body. The real reason
is one command away in result <job-id>, but nothing in the status output says so, and {
reads as a rendering glitch rather than as an error.

This is distinct from #698. There the error notification is non-terminal and the job
wedges at status: running forever. Here the turn does complete: the job reaches
status: failed with phase: failed, pid: null and completedAt set. The failure is
legible in the job log and in result — everywhere except the command a caller runs first.

Fixing #698 would not fix this. Making the error notification terminal routes the turn into
the same non-throwing completion path described below, where the summary is still { and
errorMessage is still never written.

Root cause — two independent gaps that meet

1. The summary is the first line of the raw output.

plugins/codex/scripts/codex-companion.mjs:525:

summary: firstMeaningfulLine(rawOutput, firstMeaningfulLine(failureMessage, `${taskMetadata.title} finished.`)),

firstMeaningfulLine (:174) returns the first non-blank trimmed line. On a failed turn
rawOutput is the pretty-printed error body, so that line is the opening {. Note that
shorten() (lib/codex.mjs:90) does collapse whitespace, but it is not on this path.

2. errorMessage is only written on the throwing path.

plugins/codex/scripts/lib/tracked-jobs.mjs writes errorMessage only inside the catch
(:182, :189, :199). A turn that fails server-side but completes returns normally, so the
success branch runs (:174, summary: execution.summary) and no errorMessage is ever
stored.

renderJobStatusReport already has the branch that would print it —
lib/render.mjs:437-440 — and on this path it is dead, falling through to
"No captured result payload was stored for this job."

Reproduction

Any 400 from the turn reproduces this; the trigger below is incidental. I used an effort value
the current model rejects (that vocabulary drift is #751 — not what this issue is about).

node scripts/codex-companion.mjs task --background --fresh --effort minimal "Reply with exactly: OK"
status — what a caller sees first
# Codex Job Status

- task-mtyt7j74-roqc7q | failed | rescue | Codex Task
  Summary: {
  Phase: failed
  Duration: 3s
  ...
  Progress:
    Thread ready (...).
    Turn started (...).
    Codex error: {
    Turn failed.

Both the Summary: field and the Codex error: progress line are cut to {.

The stored index row
{"id":"task-mtyt7j74-roqc7q","status":"failed","summary":"{"}

errorMessage is absent from both the index entry and the job file. The job file's keys are
id, kind, kindLabel, title, workspaceRoot, jobClass, summary, write, createdAt, status, phase, pid, logFile, request, startedAt, threadId, turnId, completedAt, result, rendered — no
errorMessage.

result — where the reason actually is
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "code": "unsupported_value",
    "message": "Unsupported value: 'minimal' is not supported with the 'gpt-5.6-terra' model. Supported values are: 'none', 'low', 'medium', 'high', 'xhigh', and 'max'.",
    "param": "reasoning.effort"
  },
  "status": 400
}

Complete and diagnostic — reached only by knowing to ask for it.

Why this is worth more than a cosmetic fix

The failure is a 400 on the first turn, about four seconds in, after the thread has already
reported ready. An agent that delegates to Codex, sees failed, and does not go on to open
result or the log concludes that Codex is broken or unavailable on that machine. That is the
wrong conclusion, and it is the one the output steers a reader toward: a summary of { looks
like the tool is malfunctioning, not like the request was rejected for a stated reason.

It costs a person the same way. status is the documented next step after a background task,
and it is the one view that currently cannot say what went wrong.

Suggested fix

Either half alone would make the failure legible; both are small.

  • Set errorMessage on the non-throwing failure path, from result.error.message when the
    turn completed with a failed status. The renderer already prints it.
  • Make the summary robust to a structured body: prefer error.message when the payload parses
    as an error, and otherwise put firstMeaningfulLine through the same whitespace collapsing
    shorten() already does, so a multi-line value can never reduce to punctuation.

The same { truncation affects the Codex error: progress line, which comes from
lib/codex.mjs:539 where message.params.error.message is interpolated raw and not shortened.

Environment

  • Plugin codex v1.0.5 as installed; every line cited re-checked against main @ v1.0.6 and
    unchanged, at identical line numbers
  • codex-cli 0.153.4
  • Windows 11 (26200), Node v24.19.0, ChatGPT sign-in
  • Model gpt-5.6-terra (pinned in ~/.codex/config.toml by the Codex desktop app)

Related: #698 (the non-terminating variant of a Codex-side failure), #695 (failure reason
discarded on the stop-gate paths), #751 (the effort vocabulary drift that made a convenient
trigger here).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with plugins/codex/scripts/codex-companion.mjs and plugins/codex/scripts/lib/tracked-jobs.mjs, then inspect lib/render.mjs and lib/codex.mjs at the cited paths. Run the provided background task reproduction and compare status with result. Done means terminal server-side failures retain their diagnostic message and status and progress output no longer collapse to {.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
backend, cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.