router-for-me/CLIProxyAPI · error
%s
Error message
%s
What it means
A failing plugin RPC whose envelope carried an error without an HTTP status: decodeEnvelopeResult re-wraps the plugin's error message verbatim as fmt.Errorf("%s", message). This is the generic passthrough for plugin-reported failures (login failed, provider error, unsupported operation), so the actionable content is the message text itself, prefixed by whatever context callPlugin adds.
Source
Thrown at internal/pluginhost/rpc_client.go:313
var envelope pluginabi.Envelope
if errUnmarshal := json.Unmarshal(raw, &envelope); errUnmarshal != nil {
return false
}
return !envelope.OK && envelope.Error != nil
}
func decodeEnvelopeResult[T any](envelope pluginabi.Envelope) (T, error) {
var zero T
if !envelope.OK {
if envelope.Error != nil {
message := strings.TrimSpace(envelope.Error.Message)
if message == "" {
message = "plugin call failed"
}
if envelope.Error.HTTPStatus > 0 {
return zero, rpcPluginError{message: message, statusCode: envelope.Error.HTTPStatus}
}
return zero, fmt.Errorf("%s", message)
}
return zero, fmt.Errorf("plugin call failed")
}
if len(envelope.Result) == 0 {
return zero, nil
}
var out T
if errDecode := json.Unmarshal(envelope.Result, &out); errDecode != nil {
return zero, errDecode
}
return out, nil
}
func marshalRPCEnvelope(result json.RawMessage) ([]byte, error) {
if result == nil {
result = json.RawMessage(`{}`)
}
return json.Marshal(pluginabi.Envelope{OK: true, Result: result})View on GitHub (pinned to 78f0c4079e)
Solutions
- Read the propagated message — it is the plugin's own explanation of the failure
- Fix the underlying condition in the plugin or its configuration (credentials, provider settings)
- If you maintain the plugin and the error should surface as an HTTP status, set Error.HTTPStatus so hosts can map it to a response code
Defensive patterns
Strategy: try-catch
Try / catch
out, err := callPlugin[T](ctx, client, method, req)
if err != nil {
var rpcErr rpcPluginError
if errors.As(err, &rpcErr) || true {
log.WithError(err).Error("plugin reported failure") // message is plugin-authored; surface it to the user verbatim
}
return err
} Prevention
- Surface the propagated message to operators instead of masking it with a generic wrapper
- In plugin code, always set a human-readable Error.Message so this path is diagnosable
When it happens
Trigger: Plugin method returns ok=false with Error{Message: "..."} and HTTPStatus <= 0 — e.g. a plugin-side OAuth exchange failing, or the plugin rejecting unsupported parameters.
Common situations: Provider-side auth failures surfaced through a plugin; plugin feature not implemented; any business error raised inside plugin code that is not mapped to an HTTP status.
Related errors
- decode host auth list request: %w
- decode host auth get request: %w
- auth_index is required
- decode host auth get runtime request: %w
- auth runtime info not found for auth_index %s
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/3125524abfcf697b.
Report an issue: GitHub.