{"record":{"id":"c2e16053af6a8fc7","repo":"RocketChat/Rocket.Chat","slug":"customoauth-failed-to-extract-email-c2e160","errorCode":null,"errorMessage":"CustomOAuth: Failed to extract email","messagePattern":"CustomOAuth: Failed to extract email","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/auth-providers/custom-oauth/custom_oauth_server.js","lineNumber":336,"sourceCode":"\t\t\tif (!value) {\n\t\t\t\tthrow new Meteor.Error('field_not_found', `Username field \"${this.usernameField}\" not found in data`, data);\n\t\t\t}\n\t\t\treturn value;\n\t\t} catch (error) {\n\t\t\tthrow new Error('CustomOAuth: Failed to extract username', error.message);\n\t\t}\n\t}\n\n\tgetEmail(data) {\n\t\ttry {\n\t\t\tconst value = fromTemplate(this.emailField, data);\n\n\t\t\tif (!value) {\n\t\t\t\tthrow new Meteor.Error('field_not_found', `Email field \"${this.emailField}\" not found in data`, data);\n\t\t\t}\n\t\t\treturn value;\n\t\t} catch (error) {\n\t\t\tthrow new Error('CustomOAuth: Failed to extract email', error.message);\n\t\t}\n\t}\n\n\tgetCustomName(data) {\n\t\ttry {\n\t\t\tconst value = fromTemplate(this.nameField, data);\n\n\t\t\tif (!value) {\n\t\t\t\treturn this.getName(data);\n\t\t\t}\n\n\t\t\treturn value;\n\t\t} catch (error) {\n\t\t\tthrow new Error('CustomOAuth: Failed to extract custom name', error.message);\n\t\t}\n\t}\n\n\tgetAvatarUrl(data) {","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/auth-providers/custom-oauth/custom_oauth_server.js#L318-L354","documentation":"getEmail()'s catch block flattens any inner failure - the field_not_found Meteor.Error, an invalid regex SyntaxError in the template, or a TypeError from a broken path - into Error('CustomOAuth: Failed to extract email', <inner message>), discarding the Meteor error code and payload details. It fires during normalizeIdentity, right after the identity endpoint responds, and aborts the whole OAuth login.","triggerScenarios":"emailField configured but its path does not resolve in the identity payload; emailField template contains an invalid '{{/regex/::path}}' expression; getEmail invoked directly on a strategy whose emailField is undefined so getNestedValue throws on undefined.split.","commonSituations":"E-mail claim withheld because the OAuth scope did not include 'email'; provider returns e-mail only via a separate endpoint; admin typo in the Email Field setting; IdP payload renamed after upgrade.","solutions":["Enable CustomOAuth debug logging and read the 'Email field not found in data' record with the actual payload","Fix emailField to an existing dot path, or clear it and use emailPath when the provider serves e-mails from a separate endpoint","Add the 'email' scope to the service configuration so the claim is released","Verify any regex formula compiles and matches before saving"],"exampleFix":"// before: Email Field = 'emailAddress'  (IdP releases 'email'; scope missing 'email' anyway)\n// Error: CustomOAuth: Failed to extract email ...\n\n// after: Email Field = 'email' and scope includes 'email'","handlingStrategy":"try-catch","validationCode":"const assertEmailTemplateOk = (tpl: string, sample: Record<string, unknown>) => {\n  try {\n    if (!fromTemplate(tpl, sample)) throw new Error(`Email Field '${tpl}' does not resolve in the identity payload`);\n  } catch (e) {\n    throw new Error(`Email Field invalid: ${e.message}`);\n  }\n};","typeGuard":null,"tryCatchPattern":"try {\n  identity.email = strategy.getEmail(identity);\n} catch (error) {\n  if (/Failed to extract email/.test(error.message)) {\n    return done(new Meteor.Error('oauth-email-mapping', 'E-mail mapping misconfigured. Contact admin.'));\n  }\n  throw error;\n}","preventionTips":["Request the 'email' scope up front","Prefer emailPath when the IdP hides e-mail from the identity endpoint","Compile-check regex formulas before saving them as field mappings"],"tags":["oauth","custom-oauth","email","field-mapping","error-wrapping"],"backgroundTag":"oauth-identity-field-mapping-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}