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

  1. Align versions: update both the Codex CLI and cc-connect so the RPC schema matches.
  2. Run `codex --version` and check the connector's release notes for a minimum required codex version.
  3. Enable debug logging to dump the raw result JSON and compare it against the expected struct.
  4. If you pin the codex binary path, point it at the version the connector was built against.
  5. 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

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


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