chenhg5/cc-connect · error
turn failed (no details)
Error message
turn failed (no details)
What it means
Raised by the codex app-server session when a `turn/completed` notification arrives with status "failed" (or an error object) but the error payload carries no usable message text. The adapter cannot report a cause, so it substitutes the placeholder "turn failed (no details)" and fails the pending turn via failTurn. It means the codex app-server aborted the turn without explaining why.
Source
Thrown at agent/codex/appserver_session.go:1137
case "item/completed":
var notif itemNotification
if err := json.Unmarshal(paramsRaw, ¬if); err == nil {
s.handleItemCompleted(notif.Item)
}
case "turn/completed":
var notif turnNotification
if err := json.Unmarshal(paramsRaw, ¬if); err == nil {
if strings.EqualFold(strings.TrimSpace(notif.Turn.Status), "failed") || notif.Turn.Error != nil {
errMsg := ""
if notif.Turn.Error != nil {
errMsg = strings.TrimSpace(notif.Turn.Error.Message)
}
if errMsg == "" {
errMsg = "turn failed (no details)"
}
s.failTurn(fmt.Errorf("%s", errMsg))
} else {
s.completeTurn()
}
}
case "thread/status/changed":
var notif struct {
ThreadID string `json:"threadId"`
Status struct {
Type string `json:"type"`
} `json:"status"`
}
if err := json.Unmarshal(paramsRaw, ¬if); err == nil && notif.Status.Type == "idle" {
// In codex 0.125+, thread going idle signals turn completion.
s.completeTurn()
}
case "account/rateLimits/updated":View on GitHub (pinned to 4000b2338a)
Solutions
- Run the codex CLI directly on the same prompt to see the underlying failure (auth expired, model unavailable, quota exhausted).
- Check codex CLI version and upgrade both the codex binary and cc-connect so the error schema matches (`codex --version`).
- Verify codex authentication (`codex login`) and API quota; silent failures often mean expired credentials.
- Inspect the codex app-server's own logs/stderr for the real error text that was not carried in the notification.
- Retry the turn; transient backend failures often surface as bare failed status.
Example fix
// before: error text missing, no way to see why
errMsg := "turn failed (no details)"
// after: log the raw notification for debugging
if notif.Turn.Error != nil {
errMsg = strings.TrimSpace(notif.Turn.Error.Message)
}
if errMsg == "" {
slog.Warn("codex turn failed without error details", "status", notif.Turn.Status)
errMsg = "turn failed (no details)"
} Defensive patterns
Strategy: try-catch
Try / catch
// consume session events
for ev := range sess.Events() {
if ev.Type == core.EventError {
if strings.Contains(ev.Error.Error(), "no details") {
slog.Warn("codex turn failed without cause; check codex CLI logs")
}
// surface to user or retry
}
} Prevention
- Keep codex CLI and cc-connect versions in sync.
- Verify codex auth (`codex login`) before long sessions.
- Monitor codex stderr for the real failure text.
- Retry failed turns once before surfacing to the user.
When it happens
Trigger: The `turn/completed` JSON-RPC notification is received where `notif.Turn.Status` equals "failed" (case-insensitive) or `notif.Turn.Error` is non-nil, AND `notif.Turn.Error.Message` is empty or whitespace-only.
Common situations: Codex app-server crashes or hits an internal error mid-turn without populating the error message; protocol version drift (codex 0.125+) where the error schema changed and the message field moved or was renamed; overloaded backend returning bare failure status; malformed turn error payloads after proxying.
Related errors
- codex app-server turn/start: %w
- %s
- codex app-server resume returned empty thread id
- codex app-server start returned empty thread id
- codex app-server thread id is empty
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/fe516e8c16e2aa0c.
Report an issue: GitHub.