RocketChat/Rocket.Chat · error · Error
CustomOAuth: Failed to extract avatar url
Error message
CustomOAuth: Failed to extract avatar url
What it means
Legacy (deprecated, non-Passport) CustomOAuth class twin of the strategy error: getAvatarUrl() throws Error('CustomOAuth: Failed to extract avatar url', <inner message>) only when fromTemplate(this.avatarField, data) throws. A missing avatar value is not an error - it logs 'Avatar field not found in data' and returns undefined - so this indicates a broken avatarField template (invalid regex in a '{{/regex/::path}}' formula, or avatarField undefined with a direct call). It fails the login via normalizeIdentity.
Source
Thrown at apps/meteor/server/lib/auth-providers/custom-oauth/custom_oauth_server.js:363
return this.getName(data);
}
return value;
} catch (error) {
throw new Error('CustomOAuth: Failed to extract custom name', error.message);
}
}
getAvatarUrl(data) {
try {
const value = fromTemplate(this.avatarField, data);
if (!value) {
logger.debug({ msg: 'Avatar field not found in data', avatarField: this.avatarField, data });
}
return value;
} catch (error) {
throw new Error('CustomOAuth: Failed to extract avatar url', error.message);
}
}
getName(identity) {
const name =
identity.name ||
identity.username ||
identity.nickname ||
identity.CharacterName ||
identity.userName ||
identity.preferred_username ||
(identity.user && identity.user.name);
return name;
}
addHookToProcessUser() {
BeforeUpdateOrCreateUserFromExternalService.push(async (serviceName, serviceData /* , options*/) => {
if (serviceName !== this.name) {View on GitHub (pinned to b2c16d5842)
Solutions
- Set Avatar Field to a plain dot path present in the identity payload, e.g. 'picture' or 'avatar_url'
- Compile-check any regex formula with new RegExp() before saving; it needs exactly one capture group
- Clear Avatar Field - extraction is optional and login succeeds without an avatar
- Check the CustomOAuth debug log for the printed payload to confirm the key name
Example fix
// before: Avatar Field = '{{/https:(.+)/::image}}' (broken regex)
// Error: CustomOAuth: Failed to extract avatar url ...
// after: Avatar Field = 'image_url' Defensive patterns
Strategy: validation
Validate before calling
// verify the avatarField template against a captured payload
const capturedIdentity = JSON.parse(savedIdentityJson); // from CustomOAuth debug logs
if (avatarFieldSetting) {
try {
fromTemplate(avatarFieldSetting, capturedIdentity);
} catch (e) {
throw new Error(`Avatar Field template is broken: ${e.message}`);
}
} Type guard
const isResolvableTemplate = (tpl: string, data: Record<string, unknown>): boolean => {
try {
return fromTemplate(tpl, data) != null;
} catch {
return false;
}
}; Try / catch
try {
identity.avatarUrl = customOAuth.getAvatarUrl(identity);
} catch (error) {
logger.warn(`avatar extraction failed: ${error.message}`);
identity.avatarUrl = undefined;
} Prevention
- Use a plain dot path for Avatar Field
- Compile-check any regex formula before saving
- Leave Avatar Field empty if the provider has no avatar claim
- Plan migration off the deprecated CustomOAuth class onto the Passport strategy
When it happens
Trigger: avatarField configured with a formula whose regex fails new RegExp() during getIdentity; avatarField left undefined by configure() and getAvatarUrl invoked directly (getNestedValue throws on undefined.split).
Common situations: Older Rocket.Chat deployments still on the deprecated class; admin copies a regex mapping from docs and mistypes it; provider payload rename after upgrade.
Related errors
- CustomOAuth: Failed to extract avatar url
- CustomOAuth: Failed to extract custom name
- CustomOAuth: Failed to extract custom name
- field_not_found
- CustomOAuth: Failed to extract username
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/b70f5172820e270f.
Report an issue: GitHub.