{"record":{"id":"364417f3542fa2e9","repo":"router-for-me/CLIProxyAPI","slug":"plugin-executor-s-refresh-returned-invalid-auth-d","errorCode":null,"errorMessage":"plugin executor %s refresh returned invalid auth data","messagePattern":"plugin executor (.+?) refresh returned invalid auth data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pluginhost/adapters_executors.go","lineNumber":752,"sourceCode":"\t}\n\tif len(data.Metadata) == 0 && auth != nil {\n\t\tdata.Metadata = cloneAnyMap(auth.Metadata)\n\t}\n\tif len(data.Attributes) == 0 && auth != nil {\n\t\tdata.Attributes = cloneStringMap(auth.Attributes)\n\t}\n\tif len(data.StorageJSON) == 0 {\n\t\tdata.StorageJSON = storageJSONFromAuth(auth)\n\t}\n\tif pluginResp.NextRefreshAfter.IsZero() && auth != nil {\n\t\tdata.NextRefreshAfter = auth.NextRefreshAfter\n\t}\n\tif !pluginResp.NextRefreshAfter.IsZero() {\n\t\tdata.NextRefreshAfter = pluginResp.NextRefreshAfter\n\t}\n\tnext := a.host.AuthDataToCoreAuth(data, \"\", data.FileName)\n\tif next == nil {\n\t\treturn nil, fmt.Errorf(\"plugin executor %s refresh returned invalid auth data\", a.Identifier())\n\t}\n\tif auth != nil {\n\t\tnext.CreatedAt = auth.CreatedAt\n\t\tnext.UpdatedAt = auth.UpdatedAt\n\t}\n\treturn next, nil\n}\n\nfunc (a *executorAdapter) CountTokens(ctx context.Context, auth *coreauth.Auth, req coreexecutor.Request, opts coreexecutor.Options) (resp coreexecutor.Response, err error) {\n\tif a == nil || a.executor == nil || a.host.isPluginFused(a.pluginID) || !a.host.pluginIdentityCurrent(a.pluginID, a.path, a.version) {\n\t\treturn coreexecutor.Response{}, fmt.Errorf(\"plugin executor %s is unavailable\", a.Identifier())\n\t}\n\tdefer func() {\n\t\tif recovered := recover(); recovered != nil {\n\t\t\ta.host.fusePlugin(a.pluginID, \"Executor.CountTokens\", recovered)\n\t\t\tresp = coreexecutor.Response{}\n\t\t\terr = fmt.Errorf(\"plugin executor %s count tokens panic: %v\", a.Identifier(), recovered)\n\t\t}","sourceCodeStart":734,"sourceCodeEnd":770,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginhost/adapters_executors.go#L734-L770","documentation":"The plugin's RefreshAuth returned data, the host normalized it via AuthDataToCoreAuth, and the result was nil — meaning the plugin's refreshed auth payload is structurally invalid (e.g. missing file name/type, unparseable storage JSON, or empty required identity fields), so no usable core Auth could be constructed.","triggerScenarios":"A plugin RefreshAuth response whose StorageJSON/FileName/attributes are empty or malformed such that AuthDataToCoreAuth returns nil; note the code backfills empty StorageJSON and NextRefreshAfter from the old auth first, so nil usually means the plugin-supplied fields themselves are invalid.","commonSituations":"Plugin returns an empty or partially-filled refresh response; plugin writes a different auth schema than the host's AuthDataToCoreAuth expects; plugin API version mismatch between plugin and host.","solutions":["Log/inspect the plugin's raw RefreshAuth response payload (data) to see which required fields are empty or malformed","Fix the plugin to return complete refresh data: valid StorageJSON, FileName, provider and ID consistent with the auth being refreshed","Align the plugin with the host's plugin API version (check AuthDataToCoreAuth requirements) and rebuild","If the plugin cannot be fixed quickly, bypass plugin refresh by re-authenticating the provider natively"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before accepting the plugin build, verify its refresh output round-trips:\nfunc validRefreshPayload(p pluginapi.AuthRefreshResponse) error {\n    if p.StorageJSON == nil || len(p.StorageJSON) == 0 { return errors.New(\"empty StorageJSON\") }\n    if strings.TrimSpace(p.FileName) == \"\" { return errors.New(\"empty FileName\") }\n    var probe map[string]any\n    return json.Unmarshal(p.StorageJSON, &probe)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Contract-test RefreshAuth responses with example payloads in CI","Pin plugin and host to matching pluginapi versions","Validate plugin responses at the boundary before converting to core auth"],"tags":["plugin","auth-refresh","data-validation","oauth"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}