Skip to content

codex-cli backend returns duplicate JSON and breaks verification #207

Description

@LuoBoT1122

codex-cli backend returns duplicate JSON and breaks verification

Description

When using FM-Agent with the local Codex CLI backend, verification fails because the captured response contains the same JSON object twice.

Configuration

[llm]
name = ""
...
backend = "codex-cli"
...

Actual behavior

Phase generation, domain-context generation, and spec generation complete successfully. Verification then retries five times with:

LLM response contains multiple JSON values

The corresponding event in fm_agent/trace/events.jsonl is recorded as:

{
  "stage": "verification",
  "status": "format_error",
  "metadata": {
    "attempt": 1,
    "parse_error": "LLM response contains multiple JSON values"
  }
}

The captured output contains duplicate JSON:

{"post_condition":"..."}
tokens used
4,250
{"post_condition":"..."}

The final verification result is:

{
  "verdict": "ERROR",
  "gaps": null,
  "error": "Failed to generate post-condition for block 1."
}

Cause analysis

run_agent_for_messages() in src/cli_backend.py starts the CLI with stderr redirected into stdout:

stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,

Codex CLI writes its terminal/session transcript to stderr and its final response to stdout. The transcript can contain a rendered copy of the final answer, while stdout contains the final answer again. After FM-Agent merges both streams, the response passed to the structured-output parser contains two valid JSON objects.

_parse_json_response() in src/llm_client.py deliberately rejects responses containing more than one JSON value:

if len(values) > 1:
    raise ValueError("LLM response contains multiple JSON values")

The attempt is therefore recorded as format_error. After five unsuccessful retries, no post-condition is returned, so the reasoner reports Failed to generate post-condition for block 1. and the final verification verdict becomes ERROR.

The retry path also appends the complete previous CLI response to the next request. Because that response contains the terminal transcript and duplicate JSON, the request context and token usage grow substantially on every retry.

Expected behavior

The successful Codex response should be parsed once, allowing verification to complete with MATCH or MISMATCH.

Environment

  • Backend: codex-cli
  • Model: local Codex default
  • Codex CLI: 0.144.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions