immich-app/immich · error · Error
User not found
Error message
User not found
What it means
Thrown by NotificationService.sendTestEmail when userRepository.get(id, { withDeleted: false }) returns null. It is a plain Error (not a NestJS HttpException), so Nest's default exception filter maps it to HTTP 500 unless wrapped. The guard intentionally excludes soft-deleted users so test emails are never sent to deactivated accounts.
Source
Thrown at server/src/services/notification.service.ts:248
});
}
}
@OnEvent({ name: 'AlbumInvite' })
async onAlbumInvite({ id, userId, senderName }: ArgOf<'AlbumInvite'>) {
await this.jobRepository.queue({ name: JobName.NotifyAlbumInvite, data: { id, recipientId: userId, senderName } });
}
@OnEvent({ name: 'SessionDelete' })
onSessionDelete({ sessionId }: ArgOf<'SessionDelete'>) {
// after the response is sent
setTimeout(() => this.websocketRepository.clientSend('on_session_delete', sessionId, sessionId), 500);
}
async sendTestEmail(id: string, dto: SystemConfigSmtpDto, tempTemplate?: string) {
const user = await this.userRepository.get(id, { withDeleted: false });
if (!user) {
throw new Error('User not found');
}
try {
await this.emailRepository.verifySmtp(dto.transport);
} catch (error) {
throw new BadRequestException('Failed to verify SMTP configuration', { cause: error });
}
const { server } = await this.getConfig({ withCache: false });
const { html, text } = await this.emailRepository.renderEmail({
template: EmailTemplate.TEST_EMAIL,
data: {
baseUrl: getExternalDomain(server),
displayName: user.name,
},
customTemplate: tempTemplate!,
});
const { messageId } = await this.emailRepository.sendEmail({View on GitHub (pinned to 199723261c)
Solutions
- Re-authenticate as an active admin so the caller's id resolves to a non-deleted user.
- Confirm the id passed to sendTestEmail is the currently authenticated user's id and not a stale value.
- Restore or re-create the soft-deleted user if the account should still exist.
- If exposing this to a wrapper service, fetch the user first and return a 404 instead of letting a bare Error surface.
Example fix
// before
const user = await this.userRepository.get(id, { withDeleted: false });
if (!user) {
throw new Error('User not found');
}
// after (use a Nest HttpException so the client sees 404, not 500)
const user = await this.userRepository.get(id, { withDeleted: false });
if (!user) {
throw new NotFoundException('User not found');
} Defensive patterns
Strategy: validation
Validate before calling
// Before calling sendTestEmail, confirm the user exists and is not deleted.
const user = await this.userRepository.get(id, { withDeleted: false });
if (!user) {
// do not call sendTestEmail; return a controlled 404 instead
throw new NotFoundException('User not found');
}
await this.notificationService.sendTestEmail(id, dto, tempTemplate); Type guard
// Narrow an Optional<User> to User before relying on it.
const isUser = (u: User | null): u is User => !!u && typeof u.id === 'string';
if (!isUser(user)) { /* skip */ } Try / catch
// Wrap the bare Error so NestJS returns a controlled status.
try {
await notificationService.sendTestEmail(id, dto);
} catch (e) {
if (e instanceof Error && e.message === 'User not found') {
throw new NotFoundException(e.message);
}
throw e;
} Prevention
- Pass the authenticated user's own id, never an arbitrary one.
- Filter soft-deleted users from your UI's user picker.
- Use a Nest HttpException (NotFoundException) instead of bare Error for HTTP-facing guards.
When it happens
Trigger: POST /system/preferences/notifications/test (admin test-email endpoint) when the authenticated admin's user record was deleted, when an invalid/stale user id was passed, or when the id belongs to a soft-deleted user.
Common situations: The admin's account was deactivated while their session was still valid; a client passed a different user's id; the database row was removed out-of-band; a test harness uses a random UUID.
Related errors
- User not found
- Failed to verify SMTP configuration
- Invalid SMTP configuration
- Failed to verify SMTP configuration
- User not found
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/37b8a27e19b21a94.
Report an issue: GitHub.