calcom/cal.diy · error · ForbiddenException
RolesGuard - User is not a member of the team with id=${team
Error message
RolesGuard - User is not a member of the team with id=${teamId}. What it means
ForbiddenException from RolesGuard when checking role access for a team-scoped (teamId present, orgId absent) request and membershipRepository.findMembershipByTeamId(teamId, user.id) returns null — the user has no Membership in that team, so the role check is skipped and a 403 is thrown.
Source
Thrown at apps/api/v2/src/modules/auth/guards/roles/roles.guard.ts:112
`RolesGuard - User is not a member of the organization with id=${orgId}.`
);
}
if (ORG_ROLES.includes(allowedRole as unknown as (typeof ORG_ROLES)[number])) {
canAccess = hasMinimumRole({
checkRole: `ORG_${membership.role}`,
minimumRole: allowedRole,
roles: ORG_ROLES,
});
}
}
// Checking the role of the user within the team
else if (Boolean(teamId) && !Boolean(orgId)) {
const membership = await this.membershipRepository.findMembershipByTeamId(Number(teamId), user.id);
if (!membership) {
this.logger.log(`User (${user.id}) is not a member of the team (${teamId}), denying access.`);
throw new ForbiddenException(`RolesGuard - User is not a member of the team with id=${teamId}.`);
}
if (TEAM_ROLES.includes(allowedRole as unknown as (typeof TEAM_ROLES)[number])) {
canAccess = hasMinimumRole({
checkRole: `TEAM_${membership.role}`,
minimumRole: allowedRole,
roles: TEAM_ROLES,
});
}
}
// Checking the role for team and org, org is above team in term of permissions
else if (Boolean(teamId) && Boolean(orgId)) {
const teamMembership = await this.membershipRepository.findMembershipByTeamId(Number(teamId), user.id);
const orgMembership = await this.membershipRepository.findMembershipByOrgId(Number(orgId), user.id);
if (!orgMembership) {
this.logger.log(`User (${user.id}) is not part of the organization (${orgId}), denying access.`);
throw new ForbiddenException(`RolesGuard - User is not part of the organization with id=${orgId}.`);View on GitHub (pinned to 176037d0af)
Solutions
- Have a team admin/owner add the user to the team and have the user accept.
- Confirm the teamId in the request path matches a team the user belongs to.
- If access was just granted, clear the RolesGuard Redis cache to drop the stale 'false'.
- For tests, seed a team Membership for the user.
Defensive patterns
Strategy: validation
Validate before calling
const membership = await membershipRepository.findMembershipByTeamId(Number(teamId), user.id);
if (!membership) {
// prompt user to be added to the team before calling
} Try / catch
try {
await client.get(`/v2/teams/${teamId}/members`);
} catch (e) {
if (e.status === 403 && /not a member of the team/.test(e.message)) {
// ask user to join the team
}
throw e;
} Prevention
- Have a team admin add the user to the team.
- Confirm the teamId is correct.
- Clear the RolesGuard cache after team membership changes.
When it happens
Trigger: Calling a team-scoped route (teamId set, no orgId) where the authenticated user has no Membership row in that team. The guard logs 'User (id) is not a member of the team (teamId), denying access.'
Common situations: User was removed from the team; team invite pending; teamId typo; user is in the parent org but never added to the specific team; test user not seeded with a team Membership.
Related errors
- RolesGuard - User is not part of the organization with id=${
- RolesGuard - User is not part of the team with id=${teamId}
- RolesGuard - user with id=${user.id} does not have the minim
- RolesGuard - User is not a member of the organization with i
- PermissionsGuard - no authentication provided. Provide eithe
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/d7fff4c47bfd996b.
Report an issue: GitHub.