n8n-io/n8n · error · NotFoundError
User not found
Error message
User not found
What it means
Returned by GET /users/:id/password-reset-link (scope user:resetPassword) when the user lookup yields no row. Note the lookup uses TypeORM findOneOrFail (which already throws EntityNotFoundError on miss), so this explicit if(!user) branch is effectively unreachable defense-in-depth; in practice you will see it only if findOneOrFail semantics change or the call is refactored to findOne.
Source
Thrown at packages/cli/src/controllers/users.controller.ts:159
};
}),
);
return usersListSchema.parse({
count,
items: this.removeSupplementaryFields(publicUsers, listQueryOptions, req.user),
});
}
@Get('/:id/password-reset-link')
@GlobalScope('user:resetPassword')
async getUserPasswordResetLink(req: UserRequest.PasswordResetLink) {
const user = await this.userRepository.findOneOrFail({
where: { id: req.params.id },
relations: ['role'],
});
if (!user) {
throw new NotFoundError('User not found');
}
if (
req.user.role.slug === GLOBAL_ADMIN_ROLE.slug &&
user.role.slug === GLOBAL_OWNER_ROLE.slug
) {
throw new ForbiddenError('Admin cannot reset password of global owner');
}
const link = this.authService.generatePasswordResetUrl(user);
return { link };
}
@Post('/:id/invite-link')
@GlobalScope('user:generateInviteLink')
async generateInviteLink(req: AuthenticatedRequest<{ id: string }, {}, {}, {}>, _res: Response) {
const inviterId = req.user.id;
const inviteeId = req.params.id;View on GitHub (pinned to 5ac6606e81)
Solutions
- Confirm the target user id exists (GET /users/:id) before requesting the reset link.
- If the user was deleted, surface that to the admin rather than retrying the reset endpoint.
- Treat a 404 here as terminal — do not retry without changing the id.
Defensive patterns
Strategy: validation
Validate before calling
async function ensureUserExists(id: string) {
const r = await fetch(`/rest/users/${id}`, { method: 'GET' });
if (r.status === 404) throw new Error(`User ${id} does not exist; cannot request reset link`);
if (!r.ok) throw new Error(`User lookup failed: ${r.status}`);
}
// await ensureUserExists(userId) before GET /users/:id/password-reset-link Try / catch
try {
await fetch(`/rest/users/${id}/password-reset-link`);
} catch (e) {
if (e.statusCode === 404) { /* user is gone; do not retry */ }
else throw e;
} Prevention
- Resolve users from a fresh GET /users list before offering the reset action.
- Do not cache user existence across sessions.
- Treat 404 from this endpoint as terminal.
When it happens
Trigger: Requesting a password reset link for an id that does not exist in the users table (deleted user, typo'd UUID, pending invite that has no user row yet), while authenticated as a user with the user:resetPassword global scope.
Common situations: Admin UI trying to reset a user that was hard-deleted between page load and click; copy-paste of an old user id; integration tests against a freshly migrated DB without seed users.
Related errors
- Admin cannot reset password of global owner
- User to generate invite link for not found
- Request to delete a user failed because the user to delete w
- Request to delete a user failed because the transferee proje
- Target user not found
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/668eb7d523040ed2.
Report an issue: GitHub.