{"record":{"id":"664b2c384a420f74","repo":"router-for-me/CLIProxyAPI","slug":"codex-live-session-field-must-contain-valid-json","errorCode":null,"errorMessage":"Codex live session field must contain valid JSON","messagePattern":"Codex live session field must contain valid JSON","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/client/codex/live/live.go","lineNumber":652,"sourceCode":"\t\tif errPart != nil {\n\t\t\treturn nil, \"\", \"\", fmt.Errorf(\"failed to parse Codex live multipart body: %w\", errPart)\n\t\t}\n\t\tpartBody, errRead := io.ReadAll(part)\n\t\terrClose := part.Close()\n\t\tif errRead != nil {\n\t\t\treturn nil, \"\", \"\", fmt.Errorf(\"failed to read Codex live multipart field: %w\", errRead)\n\t\t}\n\t\tif errClose != nil {\n\t\t\treturn nil, \"\", \"\", fmt.Errorf(\"failed to close Codex live multipart field: %w\", errClose)\n\t\t}\n\n\t\tswitch part.FormName() {\n\t\tcase \"sdp\":\n\t\t\tvalue := string(partBody)\n\t\t\tsdp = &value\n\t\tcase \"session\":\n\t\t\tif !json.Valid(partBody) {\n\t\t\t\treturn nil, \"\", \"\", errors.New(\"Codex live session field must contain valid JSON\")\n\t\t\t}\n\t\t\tsession = append(json.RawMessage(nil), partBody...)\n\t\t\tmodel = modelFromJSON(partBody)\n\t\t}\n\t}\n\tif sdp == nil {\n\t\treturn nil, \"\", \"\", errors.New(\"Codex live multipart body requires an sdp field\")\n\t}\n\tif model == \"\" {\n\t\tmodel = defaultLiveModel\n\t}\n\n\tencoded, errEncode := encodeCallRequest(*sdp, session)\n\tif errEncode != nil {\n\t\treturn nil, \"\", \"\", errEncode\n\t}\n\treturn encoded, \"application/json\", model, nil\n}","sourceCodeStart":634,"sourceCodeEnd":670,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/client/codex/live/live.go#L634-L670","documentation":"The actual round trip failed: client.Do returned an error after the request was constructed. The bridge records the error via helps.RecordAPIResponseError for telemetry, then wraps it. Cause is anything the Go http client surfaces: DNS failure, refused connections, TLS errors, context cancellation, proxy connect failures (client comes from helps.NewProxyAwareHTTPClient with the runtime config and auth).","triggerScenarios":"Unreachable host/port, DNS resolution failure, TLS certificate mismatch, context cancelled before/during dial, configured proxy unreachable, firewall dropping the connection.","commonSituations":"Egress-blocked containers; wrong proxy settings in config.yaml or environment; self-signed certs on internal endpoints; plugin calling internal services from a sandboxed network; deadlines set on the caller's context being too short.","solutions":["Inspect the wrapped error: net.Error timeouts vs tls errors vs context.Canceled point to different fixes.","Verify network egress and DNS from the host process environment (not just the dev machine).","Check proxy configuration (config.yaml / NewProxyAwareHTTPClient env) matches the deployment network.","Retry with backoff for idempotent requests when the error is a transient timeout/reset.","For TLS failures against internal endpoints, import the CA into the host's trust store."],"exampleFix":"// plugin side: distinguish cancellation from network failure\nresp, err := http.Do(ctx, req)\nif err != nil {\n    if ctx.Err() != nil {\n        return fmt.Errorf(\"request context done: %w\", ctx.Err())\n    }\n    var netErr net.Error\n    if errors.As(err, &netErr) && netErr.Timeout() && req.Method == \"GET\" {\n        // retry once with backoff\n    }\n    return fmt.Errorf(\"host http request failed: %w\", err)\n}","handlingStrategy":"retry","validationCode":"u, err := url.Parse(req.URL)\nif err != nil || u.Host == \"\" {\n    return errors.New(\"invalid URL before network call\")\n}","typeGuard":null,"tryCatchPattern":"resp, err := http.Do(ctx, req)\nif err != nil {\n    switch {\n    case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):\n        return err\n    case isTLSError(err):\n        return fmt.Errorf(\"TLS/trust issue: %w\", err) // fix certs, no retry\n    default:\n        if isIdempotent(req.Method) && attempt < maxAttempts {\n            return retryWithBackoff(...) // DNS/refused/reset may be transient\n        }\n        return err\n    }\n}","preventionTips":["Verify egress, DNS, and proxy settings from the host process environment.","Set sensible context deadlines rather than relying on transport defaults.","Distinguish retryable net.Error timeouts from permanent TLS/config failures before retrying."],"tags":["pluginhost","network","http","proxy"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}