Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code 2c356e71af fix: gracefully handle missing userWorkspace in workspaceMembers resolver
https://sonarly.com/issue/21188?type=bug

The `workspaceMembers` resolver crashes when a `workspaceMember` record exists in the workspace schema but no corresponding `userWorkspace` record exists in the core schema, causing `GetCurrentUser` to fail for all users in the affected workspace.

Fix: Changed the `workspaceMembers` resolver in `user.resolver.ts` to gracefully skip workspace members that have no corresponding `userWorkspace` record in the core schema, instead of throwing a fatal `Error('UserEntity workspace not found')`.

The fix replaces `.map()` (which crashes on the first orphaned record) with `.reduce()` that filters out workspace members with missing `userWorkspace` or missing roles. This is consistent with the team's established pattern — the singular `workspaceMember` resolver already returns `null` when data is missing (line 223-225), and commit 4ce93aee52 explicitly documents that orphaned records between workspace-schema `workspaceMember` and core-schema `userWorkspace` are a known data consistency issue.

The orphaned records are a consequence of the non-transactional cross-schema deletion in `removeUserFromWorkspaceAndPotentiallyDeleteWorkspace` (user.service.ts lines 279-286), where `workspaceMember` and `userWorkspace` are deleted in separate operations without a shared transaction. A deeper fix would make this deletion atomic, but that requires cross-schema transaction support which is architecturally complex. The pragmatic fix is to tolerate the inconsistency at read time.
2026-04-02 12:52:41 +00:00
@@ -288,14 +288,14 @@ export class UserResolver {
});
const toWorkspaceMemberDtoArgs =
workspaceMemberEntities.map<ToWorkspaceMemberDtoArgs>(
(workspaceMemberEntity) => {
workspaceMemberEntities.reduce<ToWorkspaceMemberDtoArgs[]>(
(acc, workspaceMemberEntity) => {
const userWorkspace = userWorkspacesByUserIdMap.get(
workspaceMemberEntity.userId,
);
if (!isDefined(userWorkspace)) {
throw new Error('UserEntity workspace not found');
return acc;
}
const userWorkspaceRoles = rolesByUserWorkspacesMap.get(
@@ -303,15 +303,18 @@ export class UserResolver {
);
if (!isDefined(userWorkspaceRoles)) {
throw new Error('UserEntity workspace roles not found');
return acc;
}
return {
acc.push({
userWorkspace,
userWorkspaceRoles,
workspaceMemberEntity,
};
});
return acc;
},
[],
);
return this.workspaceMemberTranspiler.toWorkspaceMemberDtos(