theonedev/onedev · error · ExplicitException

Cannot set queries and watches for service or ai account

Error message

Cannot set queries and watches for service or ai account

What it means

OneDev throws this ExplicitException from setQueriesAndWatches when the target user is not an ORDINARY type — i.e. it is a service account or AI account. Such accounts do not consume watches/queries like humans do, so the API forbids setting them. The caller must be admin or the account itself to reach this check.

Source

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

			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);

		if (!getAuthUser().equals(user)) {
			var newAuditContent = VersionedXmlDoc.fromBean(queriesAndWatches).toXML();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Filter the user list to only ORDINARY-type users before calling the endpoint
  2. If watch behavior is needed for the service account, use a dedicated ordinary user for notifications instead
  3. Skip service/AI accounts in the sync loop and log them

Example fix

// before
for (User u : users) setUserQueriesAndWatches(u.getId(), qw);
// after
for (User u : users) if (u.getType() == User.Type.ORDINARY) setUserQueriesAndWatches(u.getId(), qw);
Defensive patterns

Strategy: validation

Validate before calling

User u = getUser(userId); if (u.getType() != User.Type.ORDINARY) throw new SkipException("not ordinary user");

Type guard

boolean isOrdinary(User u) { return u != null && u.getType() == User.Type.ORDINARY; }

Try / catch

try { setUserQueriesAndWatches(userId, qw); } catch (ExplicitException e) { log.info("skip non-ordinary account {}: {}", userId, e.getMessage()); }

Prevention

When it happens

Trigger: Calling PUT /users/{userId}/queries-and-watches with userId of a service or AI account (User.getType() != ORDINARY).

Common situations: CI tooling iterating over all users (including service accounts used for integrations) and blindly updating their watch settings; scripts written before service/AI account types were introduced.

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/a905a3068404bd5f. Report an issue: GitHub.