{"record":{"id":"ac498d31fed7f034","repo":"router-for-me/CLIProxyAPI","slug":"codex-live-media-relay-capacity-exhausted","errorCode":null,"errorMessage":"Codex live media relay capacity exhausted","messagePattern":"Codex live media relay capacity exhausted","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/client/codex/live/media.go","lineNumber":281,"sourceCode":"\t}\n\tif errContext := ctx.Err(); errContext != nil {\n\t\treturn nil, \"\", errContext\n\t}\n\tbuiltProxyDialer, proxyMode, errProxy := proxyutil.BuildDialer(route.proxyURL)\n\tif errProxy != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"configure Codex live remote TCP proxy: %w\", errProxy)\n\t}\n\tproxied := proxyMode == proxyutil.ModeProxy\n\tvar proxyDialer proxy.ContextDialer\n\tif proxied {\n\t\tcontextDialer, ok := builtProxyDialer.(proxy.ContextDialer)\n\t\tif !ok {\n\t\t\treturn nil, \"\", errors.New(\"Codex live remote TCP proxy does not support cancellation\")\n\t\t}\n\t\tproxyDialer = contextDialer\n\t}\n\tif !r.limiter.acquire() {\n\t\treturn nil, \"\", errors.New(\"Codex live media relay capacity exhausted\")\n\t}\n\treleaseSlot := r.limiter.release\n\tdownstream, errDownstream := r.downstreamAPI.NewPeerConnection(r.configuration)\n\tif errDownstream != nil {\n\t\treleaseSlot()\n\t\treturn nil, \"\", fmt.Errorf(\"create downstream PeerConnection: %w\", errDownstream)\n\t}\n\tupstreamAPI := r.upstreamAPI\n\tupstreamConfiguration := r.configuration\n\tif proxied {\n\t\tupstreamAPI = r.proxyUpstreamAPI\n\t\tupstreamConfiguration.ICEServers = nil\n\t}\n\tupstream, errUpstream := upstreamAPI.NewPeerConnection(upstreamConfiguration)\n\tif errUpstream != nil {\n\t\treleaseSlot()\n\t\tif errClose := downstream.Close(); errClose != nil {\n\t\t\tlog.WithError(errClose).Debug(\"codex live media: close downstream PeerConnection after setup error\")","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/client/codex/live/media.go#L263-L299","documentation":"Post-init validation: the function table the plugin filled in is missing mandatory entries (call or free_buffer is NULL). Even though init returned success and the ABI matched, the host cannot operate a plugin without both callbacks, so it shuts it down. Indicates a broken or hand-rolled plugin implementation.","triggerScenarios":"A plugin that leaves required table slots nil — partially implemented skeleton, init that zeroes the struct, or a plugin built against a dev SDK revision where the table contract differed.","commonSituations":"Custom plugins written from scratch that fill only the fields they use; refactoring that drops table assignment; plugin author assuming fields are optional.","solutions":["Complete the plugin's function table: set both call and free_buffer in cliproxy_plugin_init.","Prefer deriving the plugin from the official SDK skeleton so table wiring stays correct.","Rebuild against the host's exact SDK version."],"exampleFix":"// plugin init: fill every required slot\n//export cliproxy_plugin_init\nfunc cliproxy_plugin_init(api *C.cliproxy_plugin_api) C.int {\n    api.abi_version = C.uint32_t(hostABI) // matches pluginHostABIVersion\n    api.call = (C.cliproxy_call_fn)(C.pluginCall)\n    api.free_buffer = (C.cliproxy_free_buffer_fn)(C.pluginFreeBuffer) // was missing\n    return 0\n}","handlingStrategy":"validation","validationCode":"// plugin-side unit test: assert the table is complete after init\ninitTable(t)\nif table.call == nil || table.free_buffer == nil {\n    t.Fatal(\"plugin function table is incomplete\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive plugins from the SDK skeleton so the function table is filled correctly.","Add a startup self-check that all required table slots are non-nil before returning from init.","Rebuild against the host's exact SDK version."],"tags":["pluginhost","native","abi","build"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}