{"record":{"id":"83bd7bbe719d4212","repo":"immich-app/immich","slug":"user-not-found","errorCode":null,"errorMessage":"User not found","messagePattern":"User not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/notification-admin.service.ts","lineNumber":28,"sourceCode":"@Injectable()\nexport class NotificationAdminService extends BaseService {\n  async create(auth: AuthDto, dto: NotificationCreateDto) {\n    const item = await this.notificationRepository.create({\n      userId: dto.userId,\n      type: dto.type ?? NotificationType.Custom,\n      level: dto.level ?? NotificationLevel.Info,\n      title: dto.title,\n      description: dto.description,\n      data: dto.data,\n    });\n\n    return mapNotification(item);\n  }\n\n  async sendTestEmail(id: string, dto: SystemConfigSmtpDto, tempTemplate?: string) {\n    const user = await this.userRepository.get(id, { withDeleted: false });\n    if (!user) {\n      throw new Error('User not found');\n    }\n\n    try {\n      await this.emailRepository.verifySmtp(dto.transport);\n    } catch (error) {\n      throw new BadRequestException('Failed to verify SMTP configuration', { cause: error });\n    }\n\n    const { server } = await this.getConfig({ withCache: false });\n    const { html, text } = await this.emailRepository.renderEmail({\n      template: EmailTemplate.TEST_EMAIL,\n      data: {\n        baseUrl: getExternalDomain(server),\n        displayName: user.name,\n      },\n      customTemplate: tempTemplate!,\n    });\n    const { messageId } = await this.emailRepository.sendEmail({","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/notification-admin.service.ts#L10-L46","documentation":"NotificationAdminService.sendTestEmail fetches the user by id to address the test email; if userRepository.get returns null (no user with that id, or it is deleted), it throws a plain Error 'User not found'. This is a precondition check before SMTP verification and rendering, so it fails fast rather than building an email to nowhere.","triggerScenarios":"POST to the admin test-email endpoint with an id that does not match a user row. Triggered by an admin entering/testing a non-existent user id, a deleted user, or a stale reference after user cleanup.","commonSituations":"Copied wrong user id; user was deleted (withDeleted:false excludes them); testing against a fresh DB with no users.","solutions":["Use GET /users (admin) to find a valid user id and retry.","If the user was deleted, either restore them or pick an active user.","Confirm the id is a valid UUID matching an existing user record."],"exampleFix":"// before\nawait adminApi.sendTestEmail('wrong-uuid', smtpDto);\n// after\nconst users = await userApi.getAll();\nawait adminApi.sendTestEmail(users[0].id, smtpDto);","handlingStrategy":"validation","validationCode":"const users = await api.userApi.getAll();\nif (!users.some((u) => u.id === userId)) {\n  throw new Error(`User ${userId} does not exist`);\n}\nawait adminApi.sendTestEmail(userId, smtpDto);","typeGuard":"const userExists = (id: string, users: { id: string }[]) =>\n  users.some((u) => u.id === id);","tryCatchPattern":"try {\n  await adminApi.sendTestEmail(userId, smtpDto);\n} catch (e) {\n  if (/User not found/.test(String(e?.message))) {\n    // refresh user list and pick a valid id\n  } else throw e;\n}","preventionTips":["Choose recipients from GET /users, not free-text input.","Restore deleted users or exclude them from the recipient list.","Validate UUIDs client-side before sending."],"tags":["api","admin","notification","email","user","validation","immich","nestjs"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}