router-for-me/CLIProxyAPI · error
host model executor is unavailable
Error message
host model executor is unavailable
What it means
During a host.model.execute callback from a plugin, the host asks its current model executor (h.currentModelExecutor()) to perform the upstream model call. If that returns nil — no executor is currently installed on the host — the callback fails with this error and the plugin's nested model call is rejected.
Source
Thrown at internal/pluginhost/host_callbacks.go:279
var req rpcStreamCloseRequest
if errUnmarshal := json.Unmarshal(request, &req); errUnmarshal != nil {
return nil, fmt.Errorf("decode stream close request: %w", errUnmarshal)
}
h.streams.close(req.StreamID, req.Error)
return marshalRPCResult(rpcEmptyResponse{})
}
func (h *Host) callHostModelExecute(ctx context.Context, request []byte) ([]byte, error) {
var req rpcHostModelExecutionRequest
if errUnmarshal := json.Unmarshal(request, &req); errUnmarshal != nil {
return nil, fmt.Errorf("decode host model execution request: %w", errUnmarshal)
}
if req.Stream {
return nil, fmt.Errorf("host.model.execute requires stream=false")
}
executor := h.currentModelExecutor()
if executor == nil {
return nil, fmt.Errorf("host model executor is unavailable")
}
skipPluginID := h.callbackCallerPluginID(ctx, req.HostCallbackID)
ctx = h.resolveCallbackContext(req.HostCallbackID, ctx)
resp, errMsg := executor.ExecuteModel(ctx, modelExecutionRequestFromPlugin(req.HostModelExecutionRequest, skipPluginID))
if errMsg != nil {
return nil, modelExecutionError(errMsg)
}
return marshalRPCResult(pluginapi.HostModelExecutionResponse{
StatusCode: resp.StatusCode,
Headers: cloneHeader(resp.Headers),
Body: append([]byte(nil), resp.Body...),
})
}
func modelExecutionRequestFromPlugin(req pluginapi.HostModelExecutionRequest, skipPluginID string) handlers.ModelExecutionRequest {
return handlers.ModelExecutionRequest{
EntryProtocol: req.EntryProtocol,
ExitProtocol: req.ExitProtocol,View on GitHub (pinned to 78f0c4079e)
Solutions
- Defer plugin work that needs host.model.execute until the host signals readiness (executor installed).
- In embeddings, wire the model executor into the host before loading plugins that use host model callbacks.
- During shutdown, stop plugins (or their callbacks) before clearing the current model executor.
Example fix
// plugin side, before
func (p *Plugin) OnLoad(ctx context.Context) error {
_, err := p.Host.ModelExecute(ctx, req) // executor may not be ready yet
return err
}
// after
func (p *Plugin) OnReady(ctx context.Context) error {
_, err := p.Host.ModelExecute(ctx, req) // host signals readiness first
return err
} Defensive patterns
Strategy: type-guard
Validate before calling
// Plugin side: check readiness before host.model.execute
if !host.ModelExecutorReady() {
return fmt.Errorf("host model executor not ready; defer this operation")
} Type guard
func hostModelExecutionReady(h *pluginhost.Host) bool {
return h != nil && h.CurrentModelExecutor() != nil
} Try / catch
resp, err := host.ModelExecute(ctx, req)
if err != nil && strings.Contains(err.Error(), "host model executor is unavailable") {
// retry after a readiness delay, or queue the work until host signals ready
return scheduleAfterReady(ctx, req)
} Prevention
- Delay plugin initialization work needing host.model.execute until the host is fully started.
- In embeddings, install the model executor before loading plugins.
When it happens
Trigger: A plugin invokes host.model.execute while the host has no current model executor: service still initializing, executor torn down during shutdown, or an embedded host configured without the model execution pipeline.
Common situations: Plugin performs a host-assisted model call during its own startup/registration before the executor is ready; embedding sdk/cliproxy without wiring the model executor; shutdown race where a plugin callback arrives after the executor was cleared.
Related errors
- plugin host is unavailable
- Codex Alpha Search API key base URL unavailable
- plugin client is closed
- target executor plugin id is required
- plugin executor %s is unavailable
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/2d17b9f97b91294c.
Report an issue: GitHub.