{"record":{"id":"06563a968bb6c476","repo":"RocketChat/Rocket.Chat","slug":"customoauth-failed-to-extract-custom-name","errorCode":null,"errorMessage":"CustomOAuth: Failed to extract custom name","messagePattern":"CustomOAuth: Failed to extract custom name","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/auth-providers/custom-oauth/customOAuth.ts","lineNumber":168,"sourceCode":"\t\t\t\tthrow new Meteor.Error('field_not_found', `Email field \"${this.emailField}\" not found in data`);\n\t\t\t}\n\t\t\treturn value as string;\n\t\t} catch (error) {\n\t\t\tthrow new Error('CustomOAuth: Failed to extract email', { cause: error });\n\t\t}\n\t}\n\n\tgetCustomName(data: Record<string, any>) {\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 as string;\n\t\t} catch (error) {\n\t\t\tthrow new Error('CustomOAuth: Failed to extract custom name', { cause: error });\n\t\t}\n\t}\n\n\tgetAvatarUrl(data: Record<string, any>) {\n\t\ttry {\n\t\t\tconst value = fromTemplate(this.avatarField, data);\n\n\t\t\tif (!value) {\n\t\t\t\tlogger.debug({ msg: 'Avatar field not found in data', avatarField: this.avatarField, data });\n\t\t\t}\n\t\t\treturn value as string;\n\t\t} catch (error) {\n\t\t\tthrow new Error('CustomOAuth: Failed to extract avatar url', { cause: error });\n\t\t}\n\t}\n\n\tgetName(identity: Record<string, any>): string {\n\t\tconst name = (identity.name ||","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/auth-providers/custom-oauth/customOAuth.ts#L150-L186","documentation":"Thrown by getCustomName's catch block when something inside the try throws. Unlike username/email, an empty nameField lookup is NOT an error (it falls back to getName, which tries name/username/nickname/preferred_username/...). So this wrapper fires only when fromTemplate itself throws — practically an invalid nameField template, e.g., a malformed {{regex::path}} formula whose regex fails to compile — since getName's plain property reads cannot throw.","triggerScenarios":"nameField configured with a broken template such as '{{/((/::name}}' (new RegExp throws SyntaxError inside getRegexpMatch); template braces mismatched so replacement/regex parsing throws during a custom OAuth login.","commonSituations":"Hand-written regex templates in the OAuth field-mapping config; copy-paste from docs with smart quotes or missing delimiters; template syntax change after upgrades.","solutions":["Correct or simplify the nameField template (valid dot path like 'user.displayName' or a well-formed '{{/^([^@]+)@/::email}}' formula)","Test the template against a sample payload before saving: fromTemplate(nameField, sampleIdentity) should not throw","If the display name is not critical, clear nameField — Rocket.Chat then derives a name via getName without erroring on missing fields"],"exampleFix":"// before\nnameField: '{{/((/::name}}' // invalid regex -> throws\n\n// after\nnameField: 'name'","handlingStrategy":"validation","validationCode":"import { fromTemplate } from './transform_helpers';\n\n// smoke-test the template before saving OAuth config\nconst sample = { name: 'Jane Doe', email: 'jane@example.com' };\nfromTemplate(nameField, sample); // throws here if the template regex is invalid — fix before deploy","typeGuard":null,"tryCatchPattern":"try {\n\tawait oauthLogin();\n} catch (e) {\n\tif (e instanceof Error && e.message === 'CustomOAuth: Failed to extract custom name') {\n\t\t// nameField template is malformed — check e.cause for the SyntaxError\n\t} else throw e;\n}","preventionTips":["Validate field templates (dot paths and {{regex::path}} formulas) in a unit test before saving them","Prefer plain dot-path mappings unless regex extraction is truly needed","Remember: a missing name is NOT an error (falls back to getName) — only broken templates throw"],"tags":["custom-oauth","oauth","field-mapping","template","regex"],"backgroundTag":"oauth-field-mapping-failed","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}