{"record":{"id":"3b3a219543143830","repo":"apolloconfig/apollo","slug":"operator-should-not-be-null-or-empty-3b3a21","errorCode":null,"errorMessage":"operator should not be null or empty","messagePattern":"operator should not be null or empty","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/UserTokenService.java","lineNumber":412,"sourceCode":"    }\n\n    Calendar maxCalendar = Calendar.getInstance();\n    maxCalendar.setTime(now);\n    maxCalendar.add(Calendar.DAY_OF_YEAR, portalConfig.userTokenMaxExpireDays());\n    if (expires.after(maxCalendar.getTime())) {\n      throw new BadRequestException(\"Token expires exceeds max allowed days:%s\",\n          portalConfig.userTokenMaxExpireDays());\n    }\n    return expires;\n  }\n\n  private int resolveRateLimit(Integer rateLimit) {\n    return rateLimit == null ? 0 : rateLimit;\n  }\n\n  private void validateOperator(String operator) {\n    if (StringUtils.isBlank(operator)) {\n      throw new BadRequestException(\"operator should not be null or empty\");\n    }\n  }\n\n  private UserTokenInfo toInfo(UserToken userToken) {\n    return toInfo(userToken, new Date());\n  }\n\n  private UserTokenInfo toInfo(UserToken userToken, Date now) {\n    UserTokenScope scope = parseScope(userToken);\n    UserTokenInfo info = new UserTokenInfo();\n    info.setId(userToken.getId());\n    info.setUserId(userToken.getUserId());\n    info.setName(userToken.getName());\n    info.setTokenPrefix(userToken.getTokenPrefix());\n    info.setStatus(resolveStatus(userToken, now));\n    info.setOperations(scope.getOperations());\n    info.setAppIds(scope.getAppIds());\n    info.setEnvs(scope.getEnvs());","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/UserTokenService.java#L394-L430","documentation":"Thrown by UserTokenService.validateOperator() when the operator string is blank (null, empty, or whitespace-only, per StringUtils.isBlank). validateOperator() is called at the start of nearly every public method: createToken, findUserTokens, revokeToken, deleteToken, rotateToken, revokeTokenForAdmin, deleteTokenForAdmin. BadRequestException → HTTP 400.","triggerScenarios":"Any call to UserTokenService that accepts an operator parameter where the operator is null, empty string, or whitespace. This includes programmatic calls where the caller failed to resolve the current user ID from the security context.","commonSituations":"The portal's request interceptor or security filter that normally injects the operator (current user) fails or is bypassed. A scheduled job or integration calls the service without a user context. The operator string was accidentally set to an empty variable.","solutions":["Ensure the operator parameter is the authenticated user's userId, resolved from Spring Security context or the request.","Add a null/blank check before calling UserTokenService methods and fail early with a clear message.","For system-level operations, use a dedicated service account ID rather than leaving it blank."],"exampleFix":"// before\nuserTokenService.createToken(request, \"\");\n// after\nString operator = userInfoHolder.getUser().getUserId();\nuserTokenService.createToken(request, operator);","handlingStrategy":"validation","validationCode":"if (StringUtils.isBlank(operator)) {\n    throw new IllegalStateException(\"No authenticated user found in security context\");\n}\nuserTokenService.createToken(request, operator);","typeGuard":"static boolean hasValidOperator(String operator) {\n    return !StringUtils.isBlank(operator);\n}","tryCatchPattern":"try {\n    userTokenService.createToken(request, operator);\n} catch (BadRequestException e) {\n    if (e.getMessage().contains(\"operator should not be null or empty\")) {\n        return Response.status(400).entity(\"Authentication context missing operator identity\").build();\n    }\n    throw e;\n}","preventionTips":["Always resolve the operator from the Spring Security context before calling service methods.","Use a dedicated service account ID for system-level operations."],"tags":["apollo-portal","user-token","validation","bad-request"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}