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

  1. Check the wrapped cause (errors.Unwrap / %v) to see if the process died, timed out, or returned a server error
  2. Verify the codex process is still alive (s.alive) and restart the session if it exited
  3. Inspect codex-side logs for the JSON-RPC error (auth, quota, invalid thread)
  4. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/f7e75abac93f0487. Report an issue: GitHub.