{"record":{"id":"2d4207fca80fba6f","repo":"router-for-me/CLIProxyAPI","slug":"plugin-auth-provider-refresh-is-unavailable-for-pr","errorCode":null,"errorMessage":"plugin auth provider refresh is unavailable for provider %s","messagePattern":"plugin auth provider refresh is unavailable for provider (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pluginhost/plugin_refresh_compat_executor.go","lineNumber":135,"sourceCode":"\t\treturn nil, fmt.Errorf(\"plugin refresh compat executor is unavailable\")\n\t}\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}\n\tif refreshed, handled, errHome := helps.RefreshAuthViaHome(ctx, e.cfg, auth); handled {\n\t\treturn refreshed, errHome\n\t}\n\tif e.host != nil {\n\t\tif refreshed, handled, errRefresh := e.host.RefreshAuth(ctx, auth); handled {\n\t\t\treturn refreshed, errRefresh\n\t\t}\n\t}\n\tif authHasRefreshToken(auth) {\n\t\tprovider := e.Identifier()\n\t\tif provider == \"\" && auth != nil {\n\t\t\tprovider = strings.TrimSpace(auth.Provider)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"plugin auth provider refresh is unavailable for provider %s\", provider)\n\t}\n\tif auth == nil {\n\t\treturn nil, nil\n\t}\n\treturn auth.Clone(), nil\n}\n\nfunc authHasRefreshToken(auth *coreauth.Auth) bool {\n\tif auth == nil || auth.Metadata == nil {\n\t\treturn false\n\t}\n\tif token, _ := auth.Metadata[\"refresh_token\"].(string); strings.TrimSpace(token) != \"\" {\n\t\treturn true\n\t}\n\tif token, _ := auth.Metadata[\"refreshToken\"].(string); strings.TrimSpace(token) != \"\" {\n\t\treturn true\n\t}\n\treturn false","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginhost/plugin_refresh_compat_executor.go#L117-L153","documentation":"The plugin-based auth refresh compatibility executor cannot refresh a credential: neither the home provider nor the plugin host handled the refresh, yet the auth carries a refresh_token in its Metadata. internal/pluginhost/plugin_refresh_compat_executor.go then returns this error naming the provider instead of silently returning a stale credential, so callers know re-login is required.","triggerScenarios":"RefreshAuth is invoked on an Auth whose Metadata['refresh_token'] is non-empty, the plugin backing that provider is not loaded/disabled/does not implement refresh, and the built-in executor registry has no handler for it either.","commonSituations":"Plugin binary missing or removed after the credential was issued; plugin version that lacks a refresh implementation; provider disabled in config but old auth file still present in auths/; auth imported from another installation whose provider plugin is not installed.","solutions":["Re-run the OAuth/login flow for that provider to mint fresh credentials (the refresh token has no usable path here)","Install/enable the plugin that owns the provider so host.RefreshAuth can handle it","Remove the stale auth file from auths/ if the provider is no longer used","Verify the provider identifier in the error matches an executor/plugin you actually ship"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if authHasRefreshToken(auth) {\n    if _, handled, _ := host.RefreshAuth(ctx, auth); !handled {\n        // no plugin can refresh this: route the user to re-login now\n    }\n}","typeGuard":null,"tryCatchPattern":"refreshed, err := executor.RefreshAuth(ctx, auth)\nif err != nil && strings.Contains(err.Error(), \"refresh is unavailable\") {\n    log.Warnf(\"credential for %s cannot be refreshed; starting interactive login\", auth.Provider)\n    return beginLoginFlow(ctx, auth.Provider)\n}","preventionTips":["Install and enable the plugin that issued the credential before its access token expires","Proactively refresh tokens on a schedule instead of waiting for expiry","Delete auth files for providers whose plugins you have removed"],"tags":["auth","oauth","plugin","refresh-token"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}