From 1cd983a33073ef9c588ef8042be063aa06adda21 Mon Sep 17 00:00:00 2001 From: Ayush Baluni <73417844+aayushbaluni@users.noreply.github.com> Date: Mon, 4 May 2026 20:28:56 +0530 Subject: [PATCH] fix: handle missing file entity in avatar deletion listener (#20192) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem When a `workspaceMember` is updated (e.g., theme/locale/avatar changes), the `WorkspaceMemberAvatarFileDeletionListener` triggers file deletion. If the referenced file entity doesn't exist in the database, an unhandled `EntityNotFoundError` crashes the NestJS server, causing a 502 loop. ## Change Wrap the file deletion call in a try-catch that gracefully handles `EntityNotFoundError` as a no-op — if the file doesn't exist, there's nothing to delete. Fixes #20191. Made with [Cursor](https://cursor.com) Co-authored-by: martmull --- ...ce-member-avatar-file-deletion.listener.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/twenty-server/src/modules/workspace-member/listeners/workspace-member-avatar-file-deletion.listener.ts b/packages/twenty-server/src/modules/workspace-member/listeners/workspace-member-avatar-file-deletion.listener.ts index 3ffb262534..b0c4c19ee1 100644 --- a/packages/twenty-server/src/modules/workspace-member/listeners/workspace-member-avatar-file-deletion.listener.ts +++ b/packages/twenty-server/src/modules/workspace-member/listeners/workspace-member-avatar-file-deletion.listener.ts @@ -1,5 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { EntityNotFoundError } from 'typeorm/error/EntityNotFoundError'; + import { ObjectRecordDeleteEvent, ObjectRecordDestroyEvent, @@ -29,7 +31,7 @@ export class WorkspaceMemberAvatarFileDeletionListener { ) { const fileIdsToDelete = this.getFileIdsToDeleteFromUpdateEvent(payload); - this.deleteCorePictures(fileIdsToDelete, payload.workspaceId); + await this.deleteCorePictures(fileIdsToDelete, payload.workspaceId); } @OnDatabaseBatchEvent('workspaceMember', DatabaseEventAction.DESTROYED) @@ -51,10 +53,17 @@ export class WorkspaceMemberAvatarFileDeletionListener { workspaceId: string, ): Promise { for (const fileId of fileIds) { - await this.fileCorePictureService.deleteCorePicture({ - workspaceId, - fileId, - }); + try { + await this.fileCorePictureService.deleteCorePicture({ + workspaceId, + fileId, + }); + } catch (error) { + if (error instanceof EntityNotFoundError) { + continue; + } + throw error; + } } }