{"record":{"id":"191baa5e7940c301","repo":"rancher/rancher","slug":"google-oauth-formgoogleoauthredirecturlfrommap","errorCode":null,"errorMessage":"[Google OAuth] formGoogleOAuthRedirectURLFromMap: no creds file present","messagePattern":"\\[Google OAuth\\] formGoogleOAuthRedirectURLFromMap: no creds file present","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/auth/providers/googleoauth/goauthconfig_actions.go","lineNumber":133,"sourceCode":"\tuserExtraInfo := g.GetUserExtraAttributes(userPrincipal)\n\tif err := retry.RetryOnConflict(retry.DefaultRetry, func() error {\n\t\treturn g.userMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo)\n\t}); err != nil {\n\t\treturn httperror.NewAPIError(httperror.ServerError, fmt.Sprintf(\"Failed to create or update userAttribute: %v\", err))\n\t}\n\n\treturn g.tokenMGR.CreateTokenAndSetCookie(user.Name, userPrincipal, groupPrincipals, providerInfo, 0, \"Token via Google OAuth Configuration\", request)\n\n}\n\nfunc (g *googleOauthProvider) formGoogleOAuthRedirectURL(goauthConfig *apiv3.GoogleOauthConfig) (string, error) {\n\treturn g.getRedirectURL([]byte(goauthConfig.OauthCredential))\n}\n\nfunc (g *googleOauthProvider) formGoogleOAuthRedirectURLFromMap(config map[string]any) (string, error) {\n\tclientCreds, ok := config[client.GoogleOauthConfigFieldOauthCredential].(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"[Google OAuth] formGoogleOAuthRedirectURLFromMap: no creds file present\")\n\t}\n\tvalue, err := common.ReadFromSecret(g.secrets, clientCreds, strings.ToLower(client.GoogleOauthConfigFieldOauthCredential))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn g.getRedirectURL([]byte(value))\n}\n\nfunc (g *googleOauthProvider) getRedirectURL(configFile []byte) (string, error) {\n\toauth2Config, err := google.ConfigFromJSON(configFile)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\t// Removing redirectURL from config because UI will set it\n\toauth2Config.RedirectURL = \"\"\n\t// access type=offline and prompt=consent (approval force), return a refresh token\n\t// UI will generate and validate the state","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/auth/providers/googleoauth/goauthconfig_actions.go#L115-L151","documentation":"formGoogleOAuthRedirectURLFromMap requires the request's config map to carry a string 'oauthCredential' entry; this error fires when that key is absent or not a string. It is the first guard before the credential is read from the secret and parsed for a redirect URL. This path runs during testAndApply-style flows that receive the config as a raw map (e.g. from the HTTP request body) rather than a typed CR.","triggerScenarios":"POSTing a testAndApply/update request whose spec map omits oauthCredential; sending oauthCredential as a non-string (map or number) in JSON; UI form submitting without the credential file because the field was left blank.","commonSituations":"Automated API calls that build the request body from a template missing the credential; JSON payloads where the file content was nested under the wrong key; clients assuming an existing stored credential is reused and omitting the field.","solutions":["Include the oauthCredential (secret name/reference) as a string field in the config map of the request body","Validate the payload shape before submitting: config[\"oauthCredential\"] must exist and be a string","If the intent is to reuse stored creds, use the flow/API that reads from the CR instead of the map-based path"],"exampleFix":"// before\nbody := map[string]any{\"hostname\": \"example.com\"}\nurl, err := p.formGoogleOAuthRedirectURLFromMap(body) // -> no creds file present\n\n// after\nbody := map[string]any{\n    \"hostname\":        \"example.com\",\n    \"oauthCredential\": \"google-oauth-client-secret\",\n}\nurl, err := p.formGoogleOAuthRedirectURLFromMap(body)","handlingStrategy":"validation","validationCode":"// hasOauthCredential validates the request map before calling the provider.\nfunc hasOauthCredential(config map[string]any) error {\n    v, ok := config[client.GoogleOauthConfigFieldOauthCredential]\n    if !ok {\n        return fmt.Errorf(\"oauthCredential is required\")\n    }\n    if _, ok := v.(string); !ok {\n        return fmt.Errorf(\"oauthCredential must be a string\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"url, err := g.formGoogleOAuthRedirectURLFromMap(config)\nif err != nil {\n    if strings.Contains(err.Error(), \"no creds file present\") {\n        return \"\", httperror.NewAPIError(httperror.InvalidBodyContent, \"oauthCredential (string) is required in the request body\")\n    }\n    return \"\", err\n}","preventionTips":["Always include oauthCredential in map-based testAndApply payloads","Validate payload shape at the HTTP handler before reaching provider code","Keep an example request body in API docs"],"tags":["go","google-oauth","validation","api-contract"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}