RocketChat/Rocket.Chat · error · Error
error-invalid-team-not-a-member
Error message
error-invalid-team-not-a-member
What it means
Thrown by TeamService.listChildren when the requesting user has no TeamMember document for the team — membership is checked with TeamMember.findOneByUserIdAndTeamId before listing team rooms. Team room listings (joined channels + public team channels + main-room discussions) are member-only. It fires after the main-room existence check.
Source
Thrown at apps/meteor/server/services/team/service.ts:1099
userId: string,
team: AtLeast<ITeam, '_id' | 'roomId' | 'type'>,
filter?: string,
type?: 'channels' | 'discussions',
sort?: Record<string, 1 | -1>,
skip = 0,
limit = 10,
): Promise<{ total: number; data: IRoom[] }> {
const mainRoom = await Rooms.findOneById(team.roomId, { projection: { _id: 1 } });
if (!mainRoom) {
throw new Error('error-invalid-team-no-main-room');
}
const isMember = await TeamMember.findOneByUserIdAndTeamId(userId, team._id, {
projection: { _id: 1 },
});
if (!isMember) {
throw new Error('error-invalid-team-not-a-member');
}
const [{ totalCount: [{ count: total }] = [], paginatedResults: data = [] }] =
(await Rooms.findChildrenOfTeam(team._id, mainRoom._id, userId, filter, type, { skip, limit, sort }).toArray()) || [];
return {
total,
data,
};
}
}
View on GitHub (pinned to e4b8178b20)
Solutions
- Verify membership first: TeamMember.findOneByUserIdAndTeamId(userId, teamId)
- Re-fetch the user's teams (teams.list for the current user) and drop stale entries from the UI
- Rejoin the team or request an invite if access is expected
- For tooling, add the service account to the team before enumerating its rooms
Example fix
// before
const rooms = await Teams.listChildren(userId, team);
// after
const isMember = await TeamMember.findOneByUserIdAndTeamId(userId, team._id, { projection: { _id: 1 } });
if (!isMember) throw new Error('error-invalid-team-not-a-member');
const rooms = await Teams.listChildren(userId, team); Defensive patterns
Strategy: validation
Validate before calling
const isMember = await TeamMember.findOneByUserIdAndTeamId(userId, teamId, { projection: { _id: 1 } });
if (!isMember) {
return API.v1.unauthorized(); // or hide the team from the user's listings
} Try / catch
try {
const rooms = await Teams.listChildren(userId, team);
} catch (err) {
if (err instanceof Error && err.message === 'error-invalid-team-not-a-member') {
// refresh the team list; remove the team from the sidebar
}
throw err;
} Prevention
- Subscribe to membership-change events so the UI drops removed teams
- Never reuse one user's credentials to enumerate another user's teams
- Check membership in route guards before rendering team room lists
When it happens
Trigger: Listing rooms of a team the user never joined; the user was just removed but the client still shows the team; a script iterates all teams under one service account that belongs to none; membership records lost during migration.
Common situations: Stale UI after membership revocation; token reuse across users in tests; admin tooling using a non-member bot account.
Related errors
AI-assisted analysis of RocketChat/Rocket.Chat@e4b8178b20 (2026-08-18).
Data as JSON: /api/errors/6703bdc4e5314ca4.
Report an issue: GitHub.