{"record":{"id":"a905a3068404bd5f","repo":"theonedev/onedev","slug":"cannot-set-queries-and-watches-for-service-or-ai-a","errorCode":null,"errorMessage":"Cannot set queries and watches for service or ai account","messagePattern":"Cannot set queries and watches for service or ai account","errorType":"http","errorClass":"ExplicitException","httpStatus":400,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java","lineNumber":567,"sourceCode":"\t\t\tuser.setTwoFactorAuthentication(null);\n\t\t\tuserService.update(user, null);\n\t\t\tauditService.audit(null, \"reset two factor authentication of account \\\"\" + user.getName() + \"\\\" via RESTful API\", null, null);\n\t\t\treturn Response.ok().build();\n\t\t}\n\t}\n\t\n\t@Api(order=2100)\n\t@Path(\"/{userId}/queries-and-watches\")\n    @POST\n    public Response setQueriesAndWatches(@PathParam(\"userId\") Long userId, @NotNull QueriesAndWatches queriesAndWatches) {\n    \tUser user = userService.load(userId);\n    \tif (!SecurityUtils.isAdministrator() && !user.equals(getAuthUser())) \n\t\t\tthrow new UnauthorizedException();\n\n\t\tif (user.isDisabled()) \n\t\t\tthrow new ExplicitException(\"Cannot set queries and watches for disabled user\");\n\t\telse if (user.getType() != ORDINARY) \n\t\t\tthrow new ExplicitException(\"Cannot set queries and watches for service or ai account\");\n\n\t\tvar oldAuditContent = VersionedXmlDoc.fromBean(getQueriesAndWatches(user)).toXML();\n\n\t\tuser.setBuildQuerySubscriptions(queriesAndWatches.buildQuerySubscriptions);\n\t\tuser.setIssueQueryWatches(queriesAndWatches.issueQueryWatches);\n\t\tuser.setPullRequestQueryWatches(queriesAndWatches.pullRequestQueryWatches);\n\t\tuser.setBuildQueries(queriesAndWatches.buildQueries);\n\t\tuser.setIssueQueries(queriesAndWatches.issueQueries);\n\t\tuser.setProjectQueries(queriesAndWatches.projectQueries);\n\t\tuser.setPullRequestQueries(queriesAndWatches.pullRequestQueries);\n\t\tuser.setPackQueries(queriesAndWatches.packQueries);\n\t\tuser.setPackQuerySubscriptions(queriesAndWatches.packQuerySubscriptions);\n\t\tuser.setWorkspaceQueries(queriesAndWatches.workspaceQueries);\n\t\tuser.setWorkspaceQuerySubscriptions(queriesAndWatches.workspaceQuerySubscriptions);\n\t\tuserService.update(user, null);\n\n\t\tif (!getAuthUser().equals(user)) {\n\t\t\tvar newAuditContent = VersionedXmlDoc.fromBean(queriesAndWatches).toXML();","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java#L549-L585","documentation":"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.","triggerScenarios":"Calling PUT /users/{userId}/queries-and-watches with userId of a service or AI account (User.getType() != ORDINARY).","commonSituations":"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.","solutions":["Filter the user list to only ORDINARY-type users before calling the endpoint","If watch behavior is needed for the service account, use a dedicated ordinary user for notifications instead","Skip service/AI accounts in the sync loop and log them"],"exampleFix":"// before\nfor (User u : users) setUserQueriesAndWatches(u.getId(), qw);\n// after\nfor (User u : users) if (u.getType() == User.Type.ORDINARY) setUserQueriesAndWatches(u.getId(), qw);","handlingStrategy":"validation","validationCode":"User u = getUser(userId); if (u.getType() != User.Type.ORDINARY) throw new SkipException(\"not ordinary user\");","typeGuard":"boolean isOrdinary(User u) { return u != null && u.getType() == User.Type.ORDINARY; }","tryCatchPattern":"try { setUserQueriesAndWatches(userId, qw); } catch (ExplicitException e) { log.info(\"skip non-ordinary account {}: {}\", userId, e.getMessage()); }","preventionTips":["Filter user lists to ORDINARY type before bulk updates","Document that service/AI accounts do not support watches","Re-check account types after OneDev upgrades that introduce new account types"],"tags":["rest-api","user-management","service-account"],"backgroundTag":"invalid-state-transition","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}