chenhg5/cc-connect · error
%s decode response: %w
Error message
%s decode response: %w
What it means
rpcRequestOverIO received a successful JSON-RPC response but failed to unmarshal the `result` field into the caller's output struct, returning an error prefixed with the RPC method name. This indicates the app-server returned a result whose shape does not match what the connector expects — usually a protocol/version mismatch.
Source
Thrown at agent/codex/session.go:760
}
if _, ok := probe["id"]; !ok {
continue
}
var resp rpcResponseEnvelope
if err := json.Unmarshal(bytes.TrimSpace(line), &resp); err != nil {
continue
}
respID, ok := rpcIDToInt64(resp.ID)
if !ok || respID != id {
continue
}
if resp.Error != nil {
return fmt.Errorf("%s: %s", method, strings.TrimSpace(resp.Error.Message))
}
if out != nil {
if err := json.Unmarshal(resp.Result, out); err != nil {
return fmt.Errorf("%s decode response: %w", method, err)
}
}
return nil
}
}
func rpcNotifyOverIO(stdin io.Writer, method string, params any) error {
payload := map[string]any{
"jsonrpc": "2.0",
"method": method,
"params": params,
}
return writeRPCMessage(stdin, payload)
}
func writeRPCMessage(w io.Writer, payload any) error {
b, err := json.Marshal(payload)
if err != nil {View on GitHub (pinned to 4000b2338a)
Solutions
- Align versions: update both the Codex CLI and cc-connect so the RPC schema matches.
- Run `codex --version` and check the connector's release notes for a minimum required codex version.
- Enable debug logging to dump the raw result JSON and compare it against the expected struct.
- If you pin the codex binary path, point it at the version the connector was built against.
- Retry after upgrade — the decode is deterministic, so a transient retry will not help.
Example fix
// before: schema drift after codex upgrade $ codex --version codex-cli 0.12.0 // renamed runtime-config fields // after: pin a compatible version $ npm i -g @openai/codex@0.9.0
Defensive patterns
Strategy: type-guard
Validate before calling
// version-gate before decoding against a schema
v := installedCodexVersion()
if !compatibleSchema(v, expectedSchemaVersion) {
return fmt.Errorf("codex %s response schema incompatible", v)
} Type guard
func decodeLenient[T any](raw json.RawMessage, out *T) error {
var probe map[string]json.RawMessage
if err := json.Unmarshal(raw, &probe); err != nil {
return fmt.Errorf("result is not an object: %w", err)
}
return json.Unmarshal(raw, out)
} Try / catch
err := rpcRequestOverIO(stdin, stdout, ctx, method, params, &out)
if err != nil && strings.Contains(err.Error(), "decode response") {
slog.Error("rpc result schema mismatch — check codex/cc-connect version match", "err", err)
// fall back to defaults; retrying cannot fix a schema mismatch
} Prevention
- Pin the codex CLI version the connector was built and tested against
- Upgrade connector and CLI together when schemas change
- Log raw result JSON at debug level to spot drift early
- Add tolerant decoding (ignore unknown fields) for forward compatibility
When it happens
Trigger: json.Unmarshal(resp.Result, out) fails inside rpcRequestOverIO for a method invoked by loadCodexRuntimeConfig — the result JSON does not fit the expected Go struct (wrong types, missing/renamed fields).
Common situations: Codex CLI updated and changed the config/runtime-info response schema; a downgrade pairs a new connector with an old binary; a non-standard result payload (e.g. an error-shaped body in `result`) from an unexpected server version.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- codex app-server resume returned empty thread id
- codex app-server start returned empty thread id
- codex app-server turn/start: %w
- turn failed (no details)
- %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/5291eccdd8e43bd0.
Report an issue: GitHub.