router-for-me/CLIProxyAPI · error
decode host auth save request: %w
Error message
decode host auth save request: %w
What it means
The host's auth.save RPC callback could not decode its request into pluginapi.HostAuthSaveRequest — invalid JSON or wrong field types. Saving is rejected before validateHostAuthSaveRequest even runs.
Source
Thrown at internal/pluginhost/auth_callbacks.go:119
authIndex := strings.TrimSpace(req.AuthIndex)
if authIndex == "" {
return nil, fmt.Errorf("auth_index is required")
}
auth, errGet := h.authByIndex(authIndex)
if errGet != nil {
return nil, errGet
}
entry := h.buildHostAuthFileEntry(auth)
if entry == nil {
return nil, fmt.Errorf("auth runtime info not found for auth_index %s", authIndex)
}
return marshalRPCResult(pluginapi.HostAuthGetRuntimeResponse{Auth: *entry})
}
func (h *Host) callHostAuthSave(ctx context.Context, request []byte) ([]byte, error) {
var req pluginapi.HostAuthSaveRequest
if errUnmarshal := json.Unmarshal(request, &req); errUnmarshal != nil {
return nil, fmt.Errorf("decode host auth save request: %w", errUnmarshal)
}
name, rawJSON, errValidate := validateHostAuthSaveRequest(req)
if errValidate != nil {
return nil, errValidate
}
path, errSave := h.saveAuthFile(ctx, name, rawJSON)
if errSave != nil {
return nil, errSave
}
return marshalRPCResult(pluginapi.HostAuthSaveResponse{
Name: name,
Path: path,
})
}
func (h *Host) listAuthFiles() ([]pluginapi.HostAuthFileEntry, error) {
manager := h.currentAuthManager()
if manager != nil {View on GitHub (pinned to 78f0c4079e)
Solutions
- Log and JSON-validate the exact payload the plugin sends for save
- Build the request with the pluginapi types (json.Marshal of a HostAuthSaveRequest) rather than manual strings
- Upgrade plugin and host together so both sides share the same pluginapi definitions
- Verify transport framing (length prefixes) if payloads arrive truncated
Defensive patterns
Strategy: validation
Validate before calling
// Plugin side: marshal structured types and pre-validate the JSON blob.
raw, err := json.Marshal(authData)
if err != nil { return err }
req := pluginapi.HostAuthSaveRequest{Name: name, JSON: raw}
if !json.Valid(req.JSON) { return errors.New("auth payload not valid JSON") } Prevention
- Never build auth JSON by string concatenation; use json.Marshal
- Validate writes with json.Valid before sending
- Upgrade plugin and host together; save payload shapes change across pluginapi versions
When it happens
Trigger: Plugin calls host auth save with a malformed payload — non-JSON bytes, wrong types for Name/JSON fields, or a truncated frame; also mismatched pluginapi struct definitions between plugin and host versions.
Common situations: Plugin serializing the auth JSON by string concatenation producing invalid JSON; plugin/host version skew after upgrading one side only; transport framing bug splitting the payload.
Related errors
- decode host auth list request: %w
- decode host auth get request: %w
- decode host auth get runtime request: %w
- auth_index is required
- decode host log request: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/cf7db20e9057b48f.
Report an issue: GitHub.