{"record":{"id":"797c1823026159dd","repo":"Budibase/budibase","slug":"email-is-required","errorCode":null,"errorMessage":"Email is required","messagePattern":"Email is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/pro/src/mappers/users.ts","lineNumber":81,"sourceCode":"    return user.userName\n  }\n\n  if (!user.emails) {\n    return undefined\n  }\n\n  return user.emails.find(x => x.primary)?.value || user.emails[0]?.value\n}\n\nexport const fromScimUser = (\n  scimUser: ScimUserResponse | ScimCreateUserRequest,\n  roles: User[\"roles\"] = {}\n): User => {\n  const existingUser = isScimUserResponse(scimUser) ? scimUser : undefined\n\n  const email = tryGetEmail(scimUser)\n  if (!email) {\n    throw new Error(\"Email is required\")\n  }\n\n  let isActive\n  switch (scimUser.active) {\n    case \"True\":\n    case \"true\":\n    case true:\n      isActive = true\n      break\n    case \"False\":\n    case \"false\":\n    case false:\n      isActive = false\n      break\n    default:\n      unreachable(scimUser.active)\n  }\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/pro/src/mappers/users.ts#L63-L99","documentation":"fromScimUser maps a SCIM user payload to a Budibase User and requires an email address. tryGetEmail looks across userName/emails etc.; if no email can be extracted the mapping cannot proceed, so it throws. SCIM identity without email cannot be represented as a Budibase user.","triggerScenarios":"POST/PUT to SCIM /Users with a payload lacking userName and emails entries (or only entries without a value/type), or a SCIM client sending users with empty email attributes during provisioning sync.","commonSituations":"IdP (Okta, Azure AD, JumpCloud) SCIM connector misconfigured to not map email to userName or emails[primary]; test payloads omitting email; attribute mapping changed in the IdP after initial setup.","solutions":["Fix the IdP SCIM attribute mapping so email is sent — map mail/userPrincipalName to userName or emails[primary].","Correct the SCIM payload to include \"emails\":[{\"value\":\"...\",\"primary\":true}] or a valid userName that is an email.","Check tryGetEmail's accepted shapes (userName, emails with value) and conform the client payload to them.","Pre-validate SCIM payloads and reject/skip users without email at the sync layer with a clearer report."],"exampleFix":"// before\n{ \"schemas\": [\"urn:...:2.0:User\"], \"name\": { \"givenName\": \"Jo\" }, \"active\": true }\n// after\n{ \"schemas\": [\"urn:...:2.0:User\"], \"userName\": \"jo@example.com\", \"emails\": [{ \"value\": \"jo@example.com\", \"primary\": true }], \"active\": true }","handlingStrategy":"validation","validationCode":"function scimUserHasEmail(u: any): boolean {\n  return Boolean(u?.userName || (Array.isArray(u?.emails) && u.emails.some(e => e?.value)))\n}","typeGuard":"function hasEmail(u: SCIMUserResponse): u is SCIMUserResponse & { email: string } {\n  return typeof tryGetEmail(u) === \"string\" && tryGetEmail(u)!.includes(\"@\")\n}","tryCatchPattern":"try {\n  const user = fromScimUser(scimPayload)\n} catch (e) {\n  if (e.message === \"Email is required\") {\n    reportSyncIssue(`SCIM user ${scimPayload.id} has no email`)\n  } else throw e\n}","preventionTips":["Map email to userName and emails[primary] in your IdP SCIM connector","Dry-run SCIM sync and flag users missing email before provisioning","Validate payloads against the SCIM core schema in tests"],"tags":["scim","users","validation","sso"],"backgroundTag":"missing-email-scim","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}