RocketChat/Rocket.Chat · error · Error
CustomOAuth: Failed to extract username
Error message
CustomOAuth: Failed to extract username
What it means
getUsername()'s catch block converts any failure - the inner field_not_found Meteor.Error, a SyntaxError from an invalid regex in the template, or a TypeError from a malformed path - into a plain Error('CustomOAuth: Failed to extract username', <inner message>). It fires during normalizeIdentity right after the identity endpoint responds and aborts the login. The second argument is just the inner message string, so the original Meteor error code and payload details are lost.
Source
Thrown at apps/meteor/server/lib/auth-providers/custom-oauth/custom_oauth_server.js:323
const error = new Error(`Failed to fetch emails from ${this.name} at ${this.emailPath}. ${err.message}`);
throw _.extend(error, { response: err.response });
}
}
retrieveCredential(credentialToken, credentialSecret) {
return OAuth.retrieveCredential(credentialToken, credentialSecret);
}
getUsername(data) {
try {
const value = fromTemplate(this.usernameField, data);
if (!value) {
throw new Meteor.Error('field_not_found', `Username field "${this.usernameField}" not found in data`, data);
}
return value;
} catch (error) {
throw new Error('CustomOAuth: Failed to extract username', error.message);
}
}
getEmail(data) {
try {
const value = fromTemplate(this.emailField, data);
if (!value) {
throw new Meteor.Error('field_not_found', `Email field "${this.emailField}" not found in data`, data);
}
return value;
} catch (error) {
throw new Error('CustomOAuth: Failed to extract email', error.message);
}
}
getCustomName(data) {
try {View on GitHub (pinned to b2c16d5842)
Solutions
- Turn on CustomOAuth debug logs and capture the payload printed with 'Username field not found in data'
- Fix the usernameField value: a plain dot path that exists in the payload, or a syntactically valid '{{/regex/::path}}' formula
- Validate the regex part with new RegExp() in a scratch shell before saving the setting
- Clear Username Field entirely if strict username mapping is not required
Example fix
// before: Username Field = '{{/^(.+)@/::email}}' but the IdP does not return e-mail -> extraction throws
// Error: CustomOAuth: Failed to extract username ...
// after: Username Field = 'preferred_username' Defensive patterns
Strategy: validation
Validate before calling
// run once when saving OAuth settings
const assertTemplateOk = (tpl: string, sample: Record<string, unknown>) => {
try {
fromTemplate(tpl, sample);
} catch (e) {
throw new Error(`Username Field template invalid: ${e.message}`);
}
}; Type guard
const isHealthyTemplate = (tpl: string | undefined, sample: Record<string, unknown>): boolean => {
if (!tpl) return false;
try {
return fromTemplate(tpl, sample) != null;
} catch {
return false;
}
}; Try / catch
try {
identity.username = strategy.getUsername(identity);
} catch (error) {
if (/Failed to extract username/.test(error.message)) {
return done(new Meteor.Error('oauth-username-mapping', 'Username mapping misconfigured. Contact admin.'));
}
throw error;
} Prevention
- Smoke-test every field template against a real payload before saving
- Do one manual SSO login after any IdP upgrade before announcing the feature
- Keep field templates as plain dot-paths unless a regex is truly required
When it happens
Trigger: Same conditions as the inner field_not_found error (usernameField path absent from the identity payload, regex formula not matching), plus template syntax problems: an invalid regex inside '{{/.../::path}}' that throws in new RegExp(), or usernameField being undefined so getNestedValue throws on undefined.split when getUsername is called directly.
Common situations: Admin typos the Username Field setting; provider payload shape changes after an IdP upgrade; strategy constructed without usernameField but getUsername invoked directly; copy-pasted formula containing smart quotes or missing braces.
Related errors
- CustomOAuth: Failed to extract username
- CustomOAuth: Failed to extract email
- field_not_found
- CustomOAuth: Failed to extract email
- field_not_found
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/803686c4724c52bc.
Report an issue: GitHub.