Guide 18 · updated 2026-10-23

OpenAI Responses API commentary parsing errors: select final structured output

A completed response can contain commentary before valid final JSON. Older Python SDK parsing can reject the commentary or return it as the structured result; the phase-aware fix preserves commentary while selecting eligible final output.

By 차도녀 gpt may · Reviewed:

Symptoms

A structured-output call can fail with ValidationError: json_invalid even when the API returned HTTP 200, status="completed", and a valid final JSON answer. In issue #3859, prose commentary before final_answer triggered the failure. A separate synthetic control made the commentary valid JSON: the old accessor then silently returned that intermediate value instead of the final answer. The reporter reproduced the SDK behavior with openai 3.8.0 and 3.14.0, using Pydantic 2.13.5.

This matters for typed extraction and agent results, where successful JSON validation alone does not establish that the selected answer is final. Popularity and difficulty have separate evidence: the official SDK metadata showed 31,917 stars and 8,058 forks on 2026-10-23, an interest proxy rather than API usage or market share; the issue supplies the concrete failure. The issue and fix date to September, not a newly observed outage on this review date.

Cause

The old parser tried each message’s output_text without considering its phase. The output_parsed accessor then selected the first parsed item. This could either reject ordinary commentary as invalid JSON or accept schema-valid commentary as the answer. Increasing schema strictness does not repair this response-selection boundary.

The merged fix passes each message’s phase into the shared parsing function. Explicit phases other than final_answer remain unparsed. A missing or null phase preserves legacy behavior; the SDK does not infer a phase from text or model name. This is distinct from dropping response_format during fallback, which changes the outgoing request.

Safe resolution

Check the resolved openai package version and move to a compatible release containing this fix. The official 3.14.1 release, published on 2026-09-15, includes it. Do not treat a plan upgrade or repeated model call as the remedy for this SDK parsing bug.

Use responses.parse(..., text_format=YourModel) and consume output_parsed after parsing succeeds. According to the SDK helper contract, output_text still concatenates commentary and final text; parsing that combined string as JSON recreates the wrong boundary. The following application guard requires an already-parsed response from a fixed SDK. It cannot repair a validation error raised earlier by an old parser.

def require_structured_result(response):
    """Accept an already-parsed response from a fixed OpenAI SDK.

    This is an application acceptance guard, not a replacement SDK parser.
    It makes no API call and deliberately never reads response.output_text.
    """
    if response.status != "completed":
        raise ValueError("Response is not completed")
    for item in response.output or []:
        if item.type != "message":
            continue
        if getattr(item, "phase", None) not in (None, "final_answer"):
            continue
        if any(part.type == "refusal" for part in item.content or []):
            raise ValueError("Final response was refused")
    result = response.output_parsed
    if result is None:
        raise ValueError("No structured result; do not fall back to commentary")
    return result

Keep invalid final JSON as an error, and distinguish refusal, incomplete response and no structured result. Do not fall back to commentary. The guard above is deliberately stricter than the convenience accessor when an eligible message contains a refusal. When replaying assistant output manually, retain the original items and their phase values as described in the official phase documentation; do not flatten them into one string.

Verification

Source review on 2026-10-23 of the official SDK fix, documentation, release and issue. No OpenAI request or live model test was performed; upstream synthetic-test results are attributed to the pull request, not reproduced here.

The upstream PR reports synthetic HTTP/SSE coverage of synchronous and asynchronous helpers, including commentary, final answers, refusals and missing phases. These are upstream test reports, not evidence of a live model call in this review.

For a pinned SDK regression check, compare final JSON only, prose commentary followed by final JSON, and schema-valid commentary followed by final JSON. In the last two cases the final object should be selected, never the intermediate object. Include unknown explicit phases, missing/null phase, refusal, no final result, invalid final JSON and incomplete responses as negative or compatibility controls. Run the same controls through both parse and stream paths when the application uses both.

This repository’s separate offline example check covers only the guard above with synthetic Python objects. Content/build validation checks the article contract, links and translation; neither check establishes SDK behavior or provider availability.

Limitations

Only the reported 3.8.0 and 3.14.0 reproductions and the 3.14.1 fix are attributed here. The first affected version, frequency across models, current live occurrence, individual account access and plan conditions were not established. No claim is made that every Astra response emits commentary or that this failure is exclusive to that model.

The SDK preserves no-phase compatibility, so it cannot recover phase information stripped by a proxy. output_parsed is the first eligible parsed result, not a guarantee of one unique final object. If the application requires exactly one result, define and test that additional contract. A later release can change other behavior; confirm the installed dependency and repeat the regression controls.

No GetBeta implementation is presented as a fix for this case. See the OpenAI API profile for provider context. Search expressions are research candidates, not verified search-volume or ranking claims.

Sources and verification scope

Source review on 2026-10-23 of the official SDK fix, documentation, release and issue. No OpenAI request or live model test was performed; upstream synthetic-test results are attributed to the pull request, not reproduced here.

Related providers