RocketChat/Rocket.Chat · error · Error

CustomOAuth: Failed to extract username

Error message

CustomOAuth: Failed to extract username

What it means

Generic wrapper thrown by getUsername's catch block around the field extraction. In almost all cases the cause is the inner Meteor.Error('field_not_found') from error 635 (template resolved to nothing), but it also wraps hard errors from fromTemplate itself, such as an invalid regex in a {{...::path}} username template. The real reason is preserved in error.cause.

Source

Thrown at apps/meteor/server/lib/auth-providers/custom-oauth/customOAuth.ts:140

		this.name = name;
		this.options = options;
		this.config = config;

		this.addHookToProcessUser();
	}

	getUsername(data: Record<string, any>) {
		try {
			const value = fromTemplate(this.usernameField, data);

			if (!value) {
				logger.debug({ msg: 'Username field not found in data', usernameField: this.usernameField, data });
				throw new Meteor.Error('field_not_found', `Username field "${this.usernameField}" not found in data`);
			}

			return value as string;
		} catch (error) {
			throw new Error('CustomOAuth: Failed to extract username', { cause: error });
		}
	}

	getEmail(data: Record<string, any>) {
		try {
			const value = fromTemplate(this.emailField, data);

			if (!value) {
				logger.debug({ msg: 'Email field not found in data', emailField: this.emailField, data });
				throw new Meteor.Error('field_not_found', `Email field "${this.emailField}" not found in data`);
			}
			return value as string;
		} catch (error) {
			throw new Error('CustomOAuth: Failed to extract email', { cause: error });
		}
	}

	getCustomName(data: Record<string, any>) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Unwrap error.cause to get the precise failure (field_not_found vs template syntax error)
  2. Fix or clear the usernameField mapping based on the provider's actual /me response
  3. Validate the template offline: unit-test fromTemplate(usernameField, sampleIdentity) before saving the config
Defensive patterns

Strategy: try-catch

Try / catch

try {
	await oauthLogin();
} catch (e) {
	const cause = (e as Error & { cause?: unknown }).cause;
	if (cause instanceof Meteor.Error && cause.error === 'field_not_found') {
		// cause.reason names the missing usernameField — fix the mapping
	} else throw e;
}

Prevention

When it happens

Trigger: usernameField configured but missing from the provider's identity payload (cause: field_not_found with the offending template); malformed usernameField template like '{{/((/::login}}' causing fromTemplate's new RegExp to throw SyntaxError.

Common situations: Field mapping typo; provider schema drift; copy-pasted template syntax errors from OAuth config docs.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/37e9d1bfcf2f55e0. Report an issue: GitHub.