theonedev/onedev · error · ExplicitException

Cannot set queries and watches for disabled user

Error message

Cannot set queries and watches for disabled user

What it means

OneDev throws this ExplicitException from the REST endpoint PUT /users/{userId}/queries-and-watches when the target user account is disabled. The API refuses to update build/issue/PR query subscriptions and watches for accounts that can no longer log in, since watch settings are meaningless for inactive accounts. Only administrators or the authenticated user themself may even reach this check.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java:565

			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");
		else if (user.getType() != ORDINARY) 
			throw new ExplicitException("Cannot set queries and watches for service or ai account");

		var oldAuditContent = VersionedXmlDoc.fromBean(getQueriesAndWatches(user)).toXML();

		user.setBuildQuerySubscriptions(queriesAndWatches.buildQuerySubscriptions);
		user.setIssueQueryWatches(queriesAndWatches.issueQueryWatches);
		user.setPullRequestQueryWatches(queriesAndWatches.pullRequestQueryWatches);
		user.setBuildQueries(queriesAndWatches.buildQueries);
		user.setIssueQueries(queriesAndWatches.issueQueries);
		user.setProjectQueries(queriesAndWatches.projectQueries);
		user.setPullRequestQueries(queriesAndWatches.pullRequestQueries);
		user.setPackQueries(queriesAndWatches.packQueries);
		user.setPackQuerySubscriptions(queriesAndWatches.packQuerySubscriptions);
		user.setWorkspaceQueries(queriesAndWatches.workspaceQueries);
		user.setWorkspaceQuerySubscriptions(queriesAndWatches.workspaceQuerySubscriptions);
		userService.update(user, null);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Re-enable the user account (uncheck 'Disabled' in user admin page or via UserResource) before updating queries and watches
  2. Skip disabled users in the calling script by checking the user's disabled flag before invoking the endpoint
  3. If the account is permanently offboarded, delete the user instead of updating their watches

Example fix

// before
restClient.setUserQueriesAndWatches(disabledUserId, qw);
// after
User u = restClient.getUser(disabledUserId);
if (!u.isDisabled()) restClient.setUserQueriesAndWatches(disabledUserId, qw);
Defensive patterns

Strategy: validation

Validate before calling

User u = getUser(userId); if (u.isDisabled()) throw new SkipException("user disabled");

Type guard

boolean canSetWatches(User u) { return u != null && !u.isDisabled(); }

Try / catch

try { setUserQueriesAndWatches(userId, qw); } catch (ExplicitException e) { log.warn("skip user {}: {}", userId, e.getMessage()); }

Prevention

When it happens

Trigger: Calling setQueriesAndWatches (REST UserResource) with a userId whose User entity has isDisabled()==true, while the caller passes the authorization check (admin or self).

Common situations: Automation scripts syncing per-user notification settings hitting a user that was recently deactivated; HR-driven offboarding disabled the account but a sync job still tries to update its watches.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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