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

  1. Verify the target user's type is ORDINARY before resetting 2FA
  2. Exclude service and AI accounts from bulk 2FA reset operations
  3. 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

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.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/f2f1f71125718f1d. Report an issue: GitHub.