RocketChat/Rocket.Chat · error · Meteor.Error
field_not_found
field_not_found
Error message
Username field "${this.usernameField}" not found in data What it means
Thrown by CustomOAuthStrategy.getUsername when fromTemplate(this.usernameField, data) resolves to a falsy value — the configured username field/template does not exist in the identity payload returned by the OAuth provider's identity endpoint. It is a Meteor.Error('field_not_found') that is immediately re-wrapped (see error 636). The usernameField template may be a dot-path ('user.login') or a {{regex::path}} formula evaluated against the provider's response body.
Source
Thrown at apps/meteor/server/lib/auth-providers/custom-oauth/customOAuth.ts:135
if (config.addAutopublishFields && typeof config.addAutopublishFields === 'object') {
Accounts.addAutopublishFields(config.addAutopublishFields);
}
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) {View on GitHub (pinned to b2c16d5842)
Solutions
- Inspect the actual identity payload (debug log 'Username field not found in data' includes the data) and correct usernameField to the real path (supports dot notation and {{regex::path}} templates)
- If the provider hides the claim, extend the requested scopes so the username claim is returned
- Alternatively clear usernameField so Rocket.Chat derives the username from other fields instead of hard-failing
Example fix
// before (provider returns { user: { login: 'jane' } })
usernameField: 'username'
// after
usernameField: 'user.login' Defensive patterns
Strategy: validation
Validate before calling
import { fromTemplate } from './transform_helpers';
// verify the mapping against a captured sample of the IdP /me response
const sample = await fetchIdentityEndpointSample();
if (!fromTemplate('user.login', sample)) {
throw new Error('usernameField does not resolve against provider payload');
} Type guard
const resolvesIn = (template: string, data: Record<string, unknown>): boolean => Boolean(fromTemplate(template, data));
Prevention
- Capture one real /me payload per provider and keep field-mapping tests against it
- Re-verify mappings after IdP upgrades that may change the userinfo schema
- Leave usernameField empty when the provider has no stable username claim
When it happens
Trigger: Custom OAuth login where usernameField is set (e.g., 'username') but the IdP's identity response uses a different shape ('login', 'preferred_username', nested 'user.login'); nested path wrong for providers like Keycloak/Nextcloud; {{regex}} formula whose capture group matches nothing so the result is undefined.
Common situations: Provider API version changed its /me response schema; field-mapping typo in the OAuth app config; scopes changed so claims disappeared; switching providers without updating field mappings.
Related errors
- CustomOAuth: Failed to extract username
- CustomOAuth: Failed to extract email
- CustomOAuth: Failed to extract custom name
- CustomOAuth: Failed to extract avatar url
- CustomOAuth: emailPath is required
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/5f964fb5241b0f1b.
Report an issue: GitHub.