chenhg5/cc-connect · error
codex app-server turn/start: %w
Error message
codex app-server turn/start: %w
What it means
The turn/start JSON-RPC request to the codex app-server returned an error; the underlying cause (timeout, process death, error response, closed pipe) is wrapped in %w. This is the transport/request-level failure, as opposed to a successful response with a bad payload.
Source
Thrown at agent/codex/appserver_session.go:500
}
params := map[string]any{
"threadId": threadID,
"input": input,
}
if model := s.GetModel(); model != "" {
params["model"] = model
}
if effort := s.GetReasoningEffort(); effort != "" {
params["effort"] = effort
}
if approval, _ := appServerModeSettings(s.mode); approval != "" {
params["approvalPolicy"] = approval
}
var resp turnStartResponse
if err := s.request("turn/start", params, &resp); err != nil {
return fmt.Errorf("codex app-server turn/start: %w", err)
}
if resp.Turn.ID == "" {
return fmt.Errorf("codex app-server turn/start returned empty turn id")
}
s.stateMu.Lock()
s.currentTurn = resp.Turn.ID
s.pendingMsgs = s.pendingMsgs[:0]
s.stateMu.Unlock()
return nil
}
func (s *appServerSession) stageImages(prompt string, images []core.ImageAttachment) (string, []string, error) {
if len(images) == 0 {
return prompt, nil, nil
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Check the wrapped cause (errors.Unwrap / %v) to see if the process died, timed out, or returned a server error
- Verify the codex process is still alive (s.alive) and restart the session if it exited
- Inspect codex-side logs for the JSON-RPC error (auth, quota, invalid thread)
- Increase the request timeout if the app-server is merely slow
Example fix
// before
if err := s.Send(ctx, prompt, nil); err != nil {
return fmt.Errorf("send failed: %v", err) // hides cause
}
// after
if err := s.Send(ctx, prompt, nil); err != nil {
var alive atomic.Bool
if !sess.IsAlive() { sess, err = agent.StartSession(ctx, opts) } // restart dead app-server
return fmt.Errorf("send failed: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
if !sess.IsAlive() {
sess, err = agent.StartSession(ctx, opts)
if err != nil { return err }
} Try / catch
if err := sess.Send(ctx, prompt, nil); err != nil {
if !sess.IsAlive() {
// process died: restart, then retry once
sess, rerr := agent.StartSession(ctx, opts)
if rerr == nil { return sess.Send(ctx, prompt, nil) }
}
return fmt.Errorf("turn/start failed: %w", err)
} Prevention
- Monitor IsAlive() and restart sessions proactively
- Keep the codex CLI up to date to avoid protocol-level rejections
- Log errors with %w so the underlying transport cause is visible
- Watch codex auth/quota status which commonly causes server-side turn rejections
When it happens
Trigger: s.request("turn/start", params, &resp) fails because the app-server process exited, the pipe closed, the request timed out waiting for a response, or the server replied with a JSON-RPC error (e.g. invalid thread, rejected turn).
Common situations: codex process crashed or was killed mid-session; session used after the read loop already rejected pending requests; codex rejected the turn due to an invalid thread id or auth/quota problem; slow app-server exceeding the request timeout.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- turn failed (no details)
- %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/f7e75abac93f0487.
Report an issue: GitHub.