theonedev/onedev · error · ExplicitException
Cannot reset two factor authentication for service or AI acc
Error message
Cannot reset two factor authentication for service or AI account
What it means
Two-factor authentication only exists for ordinary interactive-login users. If the target user's type is not ORDINARY (service or AI account), the resetTwoFactorAuthentication endpoint rejects the request. Service and AI accounts never enroll in 2FA, so there is nothing to reset.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java:547
userService.update(user, null);
return Response.ok().build();
} else {
throw new UnauthorizedException();
}
}
@Api(order=2025)
@Path("/{userId}/two-factor-authentication")
@DELETE
public Response resetTwoFactorAuthentication(@PathParam("userId") Long userId) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
User user = userService.load(userId);
if (user.isDisabled()) {
throw new ExplicitException("Cannot reset two factor authentication for disabled account");
} else if (user.getType() != ORDINARY) {
throw new ExplicitException("Cannot reset two factor authentication for service or AI account");
} else {
user.setTwoFactorAuthentication(null);
userService.update(user, null);
auditService.audit(null, "reset two factor authentication of account \"" + user.getName() + "\" via RESTful API", null, null);
return Response.ok().build();
}
}
@Api(order=2100)
@Path("/{userId}/queries-and-watches")
@POST
public Response setQueriesAndWatches(@PathParam("userId") Long userId, @NotNull QueriesAndWatches queriesAndWatches) {
User user = userService.load(userId);
if (!SecurityUtils.isAdministrator() && !user.equals(getAuthUser()))
throw new UnauthorizedException();
if (user.isDisabled())
throw new ExplicitException("Cannot set queries and watches for disabled user");View on GitHub (pinned to d44925c47c)
Solutions
- Verify the target user's type is ORDINARY before resetting 2FA
- Exclude service and AI accounts from bulk 2FA reset operations
- Check the account type via GET /users/{userId} first
Example fix
// before
await rest.post(`/users/${svc.id}/reset-two-factor-authentication`); // 400: not ORDINARY
// after
const user = await rest.get(`/users/${svc.id}`);
if (user.type === 'ORDINARY') {
await rest.post(`/users/${svc.id}/reset-two-factor-authentication`);
} Defensive patterns
Strategy: validation
Validate before calling
const user = await rest.get(`/users/${userId}`); if (user.type !== 'ORDINARY') throw new Error('2FA can only be reset for ordinary users'); Type guard
function isOrdinaryUser(user) { return user.type === 'ORDINARY'; } Try / catch
try { await rest.post(`/users/${id}/reset-two-factor-authentication`); } catch (e) { if (e.status === 400 && /service or AI account/.test(e.message)) { /* skip non-interactive accounts */ } else throw e; } Prevention
- Restrict 2FA reset scripts to ORDINARY accounts
- Remember service/AI accounts never enroll in 2FA
- Fetch account type before security operations
When it happens
Trigger: Calling POST /rest/v1/users/{userId}/reset-two-factor-authentication for a service or AI account instead of an ordinary user.
Common situations: Bulk security scripts resetting 2FA for every account; confusing a service account id with a user's id; applying incident-response 2FA resets to bot accounts.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Cannot set password for service or AI account
- Cannot set AI setting for non AI account
- Cannot reset two factor authentication for disabled account
- Reviewer not found:
- Assignee not found:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/f2f1f71125718f1d.
Report an issue: GitHub.