router-for-me/CLIProxyAPI · error

decode plugin result %s: %w

Error message

decode plugin result %s: %w

What it means

The plugin's reply decoded as a valid envelope with ok=true, but the result payload failed to unmarshal into the concrete Go type T expected by callPlugin (decode plugin result %s). The plugin and host disagree on the shape of the result — wrong field types, renamed fields, or a payload that is not the expected structure.

Source

Thrown at internal/pluginhost/rpc_client.go:168

	var zero T
	rawRequest, errMarshal := json.Marshal(sanitizePluginRequest(request))
	if errMarshal != nil {
		return zero, fmt.Errorf("marshal plugin request %s: %w", method, errMarshal)
	}
	rawResp, errCall := client.Call(ctx, method, rawRequest)
	if errCall != nil {
		return zero, errCall
	}
	var envelope pluginabi.Envelope
	if errUnmarshal := json.Unmarshal(rawResp, &envelope); errUnmarshal != nil {
		return zero, fmt.Errorf("decode plugin envelope %s: %w", method, errUnmarshal)
	}
	out, errDecode := decodeEnvelopeResult[T](envelope)
	if errDecode != nil {
		if !envelope.OK {
			return zero, errDecode
		}
		return zero, fmt.Errorf("decode plugin result %s: %w", method, errDecode)
	}
	return out, nil
}

func sanitizePluginRequest(request any) any {
	switch req := request.(type) {
	case pluginapi.AuthLoginStartRequest:
		req.HTTPClient = nil
		return req
	case pluginapi.AuthLoginPollRequest:
		req.HTTPClient = nil
		return req
	case pluginapi.AuthRefreshRequest:
		req.HTTPClient = nil
		return req
	case pluginapi.AuthModelRequest:
		req.HTTPClient = nil
		return req

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Rebuild/reinstall the plugin against the same CLIProxyAPI version as the host
  2. Inspect the raw envelope.Result for the failing method to see which field mismatches
  3. Pin host and plugin to a compatible release pair until both are upgraded together
Defensive patterns

Strategy: validation

Try / catch

out, err := callPlugin[TypedResult](ctx, client, "Method", req)
if err != nil && strings.Contains(err.Error(), "decode plugin result") {
    return fmt.Errorf("plugin/host version mismatch on %q; rebuild plugin against host v%s", "Method", version)
}

Prevention

When it happens

Trigger: Host calls e.g. Translate/Execute expecting ExecutorResult while the plugin (different version) returns a changed schema; plugin returns a JSON array where host expects an object; numeric/string field type mismatch.

Common situations: Plugin compiled against an older pluginabi/pluginapi with different struct tags; host upgraded without rebuilding third-party plugins; plugin returns null-shaped or empty-object results where a required typed field has an incompatible type.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/83850b7167f50e95. Report an issue: GitHub.