router-for-me/CLIProxyAPI · warning
plugin executor %s received nil HTTP request
Error message
plugin executor %s received nil HTTP request
What it means
HttpRequest was called with a nil *http.Request. The adapter validates the pointer before touching req.Method/req.URL and returns this error instead of panicking. This is a caller-side programming error, not a plugin or environment problem.
Source
Thrown at internal/pluginhost/adapters_executors.go:793
return coreexecutor.Response{}, errPrepare
}
pluginResp, errCountTokens := a.executor.CountTokens(ctx, buildExecutorRequest(a.host, a.provider, auth, prepared.req, prepared.opts))
if errCountTokens != nil {
return coreexecutor.Response{}, errCountTokens
}
return coreexecutor.Response{
Payload: a.translateExecutorResponse(ctx, prepared, pluginResp.Payload, false, nil),
Metadata: cloneAnyMap(pluginResp.Metadata),
Headers: cloneHeader(pluginResp.Headers),
}, nil
}
func (a *executorAdapter) HttpRequest(ctx context.Context, auth *coreauth.Auth, req *http.Request) (resp *http.Response, err error) {
if a == nil || a.executor == nil || a.host.isPluginFused(a.pluginID) || !a.host.pluginIdentityCurrent(a.pluginID, a.path, a.version) {
return nil, fmt.Errorf("plugin executor %s is unavailable", a.Identifier())
}
if req == nil {
return nil, fmt.Errorf("plugin executor %s received nil HTTP request", a.Identifier())
}
defer func() {
if recovered := recover(); recovered != nil {
a.host.fusePlugin(a.pluginID, "Executor.HttpRequest", recovered)
resp = nil
err = fmt.Errorf("plugin executor %s http request panic: %v", a.Identifier(), recovered)
}
}()
body, errReadAll := readAndRestoreRequestBody(req)
if errReadAll != nil {
return nil, fmt.Errorf("read plugin http request body: %w", errReadAll)
}
pluginResp, errHTTPRequest := a.executor.HttpRequest(ctx, pluginapi.ExecutorHTTPRequest{
AuthID: authID(auth),
AuthProvider: authProvider(auth),
Method: req.Method,
URL: req.URL.String(),
Headers: cloneHeader(req.Header),View on GitHub (pinned to 78f0c4079e)
Solutions
- Audit the call site of HttpRequest and check the request for nil before calling
- Fix the upstream code that produced a nil request (e.g. http.NewRequest error ignored) and propagate that error instead
- Add a unit test covering the nil-request path to lock in the guard
Example fix
// before
resp, err := adapter.HttpRequest(ctx, auth, req) // req may be nil
// after
if req == nil {
return nil, errors.New("inbound request is nil")
}
resp, err := adapter.HttpRequest(ctx, auth, req) Defensive patterns
Strategy: validation
Validate before calling
// Before calling the adapter:
if req == nil {
return nil, errors.New("inbound request is nil")
}
resp, err := adapter.HttpRequest(ctx, auth, req) Type guard
func isHTTPRequestReady(req *http.Request) bool {
return req != nil && req.URL != nil && req.Method != ""
} Prevention
- Never ignore errors from http.NewRequest — propagate them instead of forwarding nil
- Lint wrapper/proxy layers for nil-request forwarding
- Unit-test the nil-request path
When it happens
Trigger: Passing a nil *http.Request to executorAdapter.HttpRequest — e.g. a handler that returns nil on a malformed inbound request and forwards it without checking, or a test that passes nil.
Common situations: Wrapper/proxy code that constructs requests conditionally and forwards nil on failure; refactors that drop a nil check; unit tests with nil literals.
Related errors
- plugin executor %s http request panic: %v
- read plugin http request body: %w
- plugin host is unavailable
- failed to read plugin management request body
- Codex live request body too large
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/082864498e07f7c8.
Report an issue: GitHub.