GPT-5.6 Terra intermittently returns an empty successful final response after tool use, prematurely ending agent loops
Summary
Immediately after GPT-5.6 became available in my environment, long-running coding sessions using the Codex endpoint began intermittently ending in the middle of a task after a successful tool call.
The endpoint returns a syntactically complete, successful response with:
- HTTP 200
stopReason: "stop"- a valid response ID
text_startfollowed bytext_end- no
text_deltaevents and zero visible text - no provider/runtime diagnostics
Because the response is classified as a normal stop, the client correctly considers the agent turn complete even though the task is still in progress. Sending a follow-up such as continue immediately resumes the work.
This did not occur for me before the GPT-5.6 rollout. I am not claiming the rollout is definitively causal, but the regression began immediately after switching to GPT-5.6.
Environment
- Client: Pi coding agent
0.80.6 - Provider integration:
openai-codexusing ChatGPT subscription authentication - Model:
gpt-5.6-terra - Reasoning effort:
medium - OS: Arch Linux
- Node:
v26.4.0 - Transport during the captured reproduction: explicit SSE
httpIdleTimeoutMs:120000- IPv6: disabled system-wide
- Workload: long, multi-step coding task with many tool calls
- Session context at the captured occurrence: approximately 258k total tokens
Captured stream evidence
A representative empty final response:
{
"model": "openai-codex/gpt-5.6-terra",
"elapsedMs": 5120,
"stopReason": "stop",
"textChars": 0,
"thinkingChars": 0,
"contentTypes": ["thinking", "text"],
"streamEventCounts": {
"thinking_start": 1,
"thinking_end": 1,
"text_start": 1,
"text_end": 1
},
"usage": {
"input": 1406,
"output": 14,
"cacheRead": 257024,
"cacheWrite": 0,
"reasoning": 8,
"totalTokens": 258444
},
"responseId": "resp_03a93f16526e1365016a520f55ee088199a81683d3d457b0ff",
"diagnostics": null
}
The immediately preceding response was a normal tool-use response:
{
"stopReason": "toolUse",
"textChars": 0,
"thinkingChars": 112,
"contentTypes": ["thinking", "toolCall"],
"streamEventCounts": {
"thinking_start": 1,
"thinking_delta": 6,
"thinking_end": 1,
"toolcall_start": 1,
"toolcall_delta": 346,
"toolcall_end": 1
}
}
The tool executed successfully. Pi then started the next model turn and received the empty successful final response above. There was no missing HTTP response and no truncated SSE event sequence.
Observed behavior
- The model performs several normal reasoning/tool-use steps.
- A tool completes successfully.
- The next Codex response returns
stopwith an empty text block. - The agent loop ends because the response is a successful completion.
- The task remains incomplete.
- A manual
continueimmediately resumes normal tool use. - The same empty-final condition can recur after additional progress.
Sometimes the transcript visually appears to stop after a thinking block, because the final text block exists but contains no text.
Network and transport checks
I attempted to rule out a local connection failure:
- Changed Wi-Fi networks; the behavior persisted.
- IPv6 is disabled (
net.ipv6.conf.all.disable_ipv6 = 1). - IPv4 connectivity to
api.openai.comcompleted normally. - The captured reproduction had complete SSE lifecycle events and a successful
stop, rather than a disconnect/error. - Manual compaction was attempted, but the behavior persisted in the ongoing session.
These observations make this look more like an empty model/provider completion than a network timeout. A clean fresh-session/alternate-model comparison is still useful and I can provide additional results.
Workaround
I implemented a Pi extension that detects this exact condition:
assistant stopReason == "stop"
AND visible final text is empty
AND the run used one or more tools
When the agent becomes idle, the extension injects a hidden follow-up equivalent to:
Your previous response ended successfully but contained no visible final text. Continue the existing task from its current state without repeating completed work.
This successfully resumes the task. The workaround initially allowed two retries, but the empty successful response sometimes recurred after the model made substantial additional progress, so I changed it to allow continued retries until manually stopped.
This confirms that the session/tool state remains usable and that a new model turn can continue normally; only the empty successful final response prematurely terminates the loop.
Expected behavior
For an incomplete tool-driven task, the model should either:
- emit another tool call,
- emit a non-empty final/blocking response, or
- return a retryable error if the response cannot be completed.
A successful stop containing an empty text block should not silently terminate an active task.
Possibly related
- #27352 — Codex marks a turn complete while follow-up work is still needed.
- #26860 — model stops automatically mid-task without a useful final response.
The distinction in this report is the concrete wire-level signature: text_start → text_end, no text_delta, then successful stop immediately after tool use.
I can provide additional sanitized stream logs, response IDs, and A/B results across GPT-5.6 variants or earlier models if useful.