{"record":{"id":"a7ded811bba2e749","repo":"router-for-me/CLIProxyAPI","slug":"realtime-client-secrets-require-an-sdp-or-json-cal","errorCode":null,"errorMessage":"Realtime client secrets require an SDP or JSON call request","messagePattern":"Realtime client secrets require an SDP or JSON call request","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/client/codex/live/live.go","lineNumber":561,"sourceCode":"\t\tcontentType = \"application/json\"\n\t}\n\treturn body, contentType, model, nil\n}\n\nfunc applyClientSecretCallSession(body []byte, contentType, model string, session json.RawMessage) ([]byte, string, string, error) {\n\tif len(session) == 0 {\n\t\treturn body, contentType, model, nil\n\t}\n\tmediaType, _, errMediaType := mime.ParseMediaType(contentType)\n\tif errMediaType == nil && (strings.EqualFold(mediaType, \"application/sdp\") || strings.EqualFold(mediaType, \"text/plain\")) {\n\t\tencoded, errEncode := encodeCallRequest(string(body), session)\n\t\tif errEncode != nil {\n\t\t\treturn nil, \"\", \"\", errEncode\n\t\t}\n\t\treturn encoded, \"application/json\", modelFromJSON(session), nil\n\t}\n\tif errMediaType != nil || !strings.EqualFold(mediaType, \"application/json\") {\n\t\treturn nil, \"\", \"\", errors.New(\"Realtime client secrets require an SDP or JSON call request\")\n\t}\n\tvar payload map[string]json.RawMessage\n\tif errUnmarshal := json.Unmarshal(body, &payload); errUnmarshal != nil {\n\t\treturn nil, \"\", \"\", fmt.Errorf(\"failed to decode Realtime call request: %w\", errUnmarshal)\n\t}\n\tpayload[\"session\"] = append(json.RawMessage(nil), session...)\n\tencoded, errMarshal := json.Marshal(payload)\n\tif errMarshal != nil {\n\t\treturn nil, \"\", \"\", fmt.Errorf(\"failed to encode Realtime call request: %w\", errMarshal)\n\t}\n\treturn encoded, \"application/json\", modelFromJSON(session), nil\n}\n\nfunc rewriteCallRequestModel(body []byte, contentType, model string) ([]byte, string, error) {\n\tupstreamModel := codexRealtimeModel(model)\n\tmediaType, _, errMediaType := mime.ParseMediaType(contentType)\n\tif errMediaType != nil || !strings.EqualFold(mediaType, \"application/json\") || len(bytes.TrimSpace(body)) == 0 {\n\t\treturn body, upstreamModel, nil","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/client/codex/live/live.go#L543-L579","documentation":"Defensive guard in hostHTTPClient.doHTTP: the method is invoked on a nil client or a client whose host pointer is nil. In practice this means the HTTP bridge object was used after being torn down or was constructed outside the host.","triggerScenarios":"Calling Do/DoStream on a zero-value hostHTTPClient, or retaining the bridge after the Host was shut down and its back-references dropped.","commonSituations":"Embedders stashing the plugin-side HTTP client beyond the plugin/host lifecycle; races during shutdown; test code constructing the bridge directly.","solutions":["Obtain the HTTP client from the live host API during a callback, not from a cached global.","Do not issue host HTTP calls after host shutdown has begun.","In tests, construct the bridge through the Host, not as a zero value."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Go: guard before use\nif c == nil || c.host == nil {\n    return errors.New(\"host http client is unavailable\")\n}","tryCatchPattern":"resp, err := client.Do(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"host http client is unavailable\") {\n    // lifecycle bug: client used outside the host's lifetime — re-acquire from the live host API\n}","preventionTips":["Fetch the HTTP client from the live host API per callback instead of caching it globally.","Never use host bridges after shutdown begins.","In tests, obtain the client from a constructed Host."],"tags":["pluginhost","lifecycle","http"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}