{"record":{"id":"ed37ffac9556c095","repo":"calcom/cal.diy","slug":"rolesguard-user-is-not-part-of-the-team-with-id","errorCode":null,"errorMessage":"RolesGuard - User is not part of the team with id=${teamId} and/or, is not an admin nor an owner of the organization with id=${orgId}.","messagePattern":"RolesGuard - User is not part of the team with id=(.+?) and/or, is not an admin nor an owner of the organization with id=(.+?)\\.","errorType":"http","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"apps/api/v2/src/modules/auth/guards/roles/roles.guard.ts","lineNumber":143,"sourceCode":"      const teamMembership = await this.membershipRepository.findMembershipByTeamId(Number(teamId), user.id);\n      const orgMembership = await this.membershipRepository.findMembershipByOrgId(Number(orgId), user.id);\n\n      if (!orgMembership) {\n        this.logger.log(`User (${user.id}) is not part of the organization (${orgId}), denying access.`);\n        throw new ForbiddenException(`RolesGuard - User is not part of the organization with id=${orgId}.`);\n      }\n\n      // if the role checked is a TEAM role\n      if (TEAM_ROLES.includes(allowedRole as unknown as (typeof TEAM_ROLES)[number])) {\n        // if the user is admin or owner of org, allow request because org > team\n        if (`ORG_${orgMembership.role}` === \"ORG_ADMIN\" || `ORG_${orgMembership.role}` === \"ORG_OWNER\") {\n          canAccess = true;\n        } else {\n          if (!teamMembership) {\n            this.logger.log(\n              `User (${user.id}) is not part of the team (${teamId}) and/or, is not an admin nor an owner of the organization (${orgId}).`\n            );\n            throw new ForbiddenException(\n              `RolesGuard - User is not part of the team with id=${teamId} and/or, is not an admin nor an owner of the organization with id=${orgId}.`\n            );\n          }\n\n          // if user is not admin nor an owner of org, and is part of the team, then check user team membership role\n          canAccess = hasMinimumRole({\n            checkRole: `TEAM_${teamMembership.role}`,\n            minimumRole: allowedRole,\n            roles: TEAM_ROLES,\n          });\n        }\n      }\n\n      // if allowed role is a ORG ROLE, check org membersip role\n      else if (ORG_ROLES.includes(allowedRole as unknown as (typeof ORG_ROLES)[number])) {\n        canAccess = hasMinimumRole({\n          checkRole: `ORG_${orgMembership.role}`,\n          minimumRole: allowedRole,","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/auth/guards/roles/roles.guard.ts#L125-L161","documentation":"ForbiddenException from RolesGuard in the combined org+team branch when: (a) the allowedRole is a TEAM role, (b) the user IS a member of the org but NOT as ORG_ADMIN/ORG_OWNER (so org-over-team escalation does not apply), and (c) the user has no teamMembership row. Because org admins/owners are auto-allowed for any team role, this only fires for non-admin org members who are also absent from the specific team.","triggerScenarios":"Calling an org+team route requiring a TEAM_* role, where the user is e.g. an ORG_MEMBER of the org and has no Membership in the target team. The guard logs both the team-absence and the not-admin/owner context.","commonSituations":"Org member tries to manage a team they weren't added to; user was removed from the team but retained org membership; recent role change not yet reflected (cache); test seed has org Membership but not team Membership.","solutions":["Have a team admin/owner add the user to the team, OR have an org owner promote the user to ORG_ADMIN/ORG_OWNER (which grants cross-team access).","Confirm the teamId matches a team inside the org the user belongs to.","Clear the RolesGuard Redis cache if a membership/role was just updated.","For tests, seed a team Membership row (or promote to ORG_ADMIN in the org Membership)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const orgMembership = await membershipRepository.findMembershipByOrgId(Number(orgId), user.id);\nconst teamMembership = await membershipRepository.findMembershipByTeamId(Number(teamId), user.id);\nconst isOrgPrivileged = orgMembership && ['ADMIN','OWNER'].includes(orgMembership.role);\nif (!isOrgPrivileged && !teamMembership) {\n  // user must either be added to the team OR promoted to ORG_ADMIN/ORG_OWNER\n}","typeGuard":null,"tryCatchPattern":"try {\n  await client.get(`/v2/orgs/${orgId}/teams/${teamId}/members`);\n} catch (e) {\n  if (e.status === 403 && /not part of the team.*not an admin nor an owner/.test(e.message)) {\n    // request team membership OR org owner promotion\n  }\n  throw e;\n}","preventionTips":["Non-admin org members must also be team members to access team-scoped routes.","Promote to ORG_ADMIN/ORG_OWNER to grant cross-team access.","Clear the RolesGuard cache after role/membership changes."],"tags":["auth","roles","membership","team","organization","guard"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}