chenhg5/cc-connect · error
codex app-server start returned empty thread id
Error message
codex app-server start returned empty thread id
What it means
This error is returned when starting a fresh codex thread: the "thread/start" JSON-RPC request succeeded but the response carried an empty thread id. Since all later turns depend on the thread id, the library refuses to continue with an empty value. It usually signals protocol/schema drift or a degraded app-server response.
Source
Thrown at agent/codex/appserver_session.go:348
var resp threadResumeResponse
if err := s.request("thread/resume", params, &resp); err != nil {
return err
}
if resp.Thread.ID == "" {
return fmt.Errorf("codex app-server resume returned empty thread id")
}
s.applyThreadRuntimeState(resp.Cwd, resp.Model, resp.ReasoningEffort)
s.threadID.Store(resp.Thread.ID)
slog.Info("codex app-server thread resumed", "thread_id", resp.Thread.ID)
return nil
}
var resp threadStartResponse
if err := s.request("thread/start", s.threadRequestParams(), &resp); err != nil {
return err
}
if resp.Thread.ID == "" {
return fmt.Errorf("codex app-server start returned empty thread id")
}
s.applyThreadRuntimeState(resp.Cwd, resp.Model, resp.ReasoningEffort)
s.threadID.Store(resp.Thread.ID)
slog.Info("codex app-server thread started", "thread_id", resp.Thread.ID)
return nil
}
func (s *appServerSession) threadRequestParams() map[string]any {
params := map[string]any{
"experimentalRawEvents": false,
"persistExtendedHistory": false,
}
if model := s.GetModel(); model != "" {
params["model"] = model
}
if approval, sandbox := appServerModeSettings(s.mode); approval != "" {
params["approvalPolicy"] = approval
if sandbox != "" {View on GitHub (pinned to 4000b2338a)
Solutions
- Capture/log the raw thread/start response and diff against threadStartResponse; fix the struct mapping.
- Upgrade/downgrade the codex CLI so client and server agree on the schema.
- Restart the app-server if it is returning degenerate empty threads.
- Verify the request params (threadRequestParams) are acceptable to the server — some servers return empty threads on rejected-but-unreported params.
Example fix
// before
if resp.Thread.ID == "" {
return fmt.Errorf("codex app-server start returned empty thread id")
}
// after
if resp.Thread.ID == "" {
slog.Error("codex thread/start missing id", "raw", rawRespBody)
return fmt.Errorf("codex app-server start returned empty thread id (check codex CLI version / protocol schema)")
} Defensive patterns
Strategy: type-guard
Validate before calling
// Validate the start response before storing the thread id
if resp.Thread.ID == "" {
return errors.New("codex thread/start returned no id; check CLI version/protocol")
} Type guard
func hasValidThread(resp threadStartResponse) bool {
return resp.Thread.ID != ""
} Try / catch
if err := session.Send(ctx, prompt); err != nil {
if strings.Contains(err.Error(), "start returned empty thread id") {
slog.Error("codex thread/start bad response; capture raw body and CLI version")
// retry start once, then surface to user
}
return err
} Prevention
- Pin the codex CLI version and re-run protocol integration tests on upgrades.
- Log raw response payloads on schema-mismatch errors.
- Restart the app-server if empty threads recur (degenerate server state).
- Keep threadStartResponse struct in sync with upstream protocol docs.
When it happens
Trigger: Calling Send (with no resumeID) on a codex session; the app-server responds to thread/start but resp.Thread.ID is "" — server returned an unexpected shape or an empty thread object.
Common situations: Codex CLI upgrade changed thread/start response schema; app-server in a bad state (e.g. failed model backend) returning an empty thread; client struct fields misaligned with new JSON keys.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- codex app-server resume returned empty thread id
- codex app-server turn/start: %w
- turn failed (no details)
- %s
- %s timed out
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/de1286a9375bfaa9.
Report an issue: GitHub.