apolloconfig/apollo · error · BadRequestException
operator should not be null or empty
Error message
operator should not be null or empty
What it means
HTTP 400 (BadRequestException). Thrown by OpenApiOperatorResolver.resolve when auth type is CONSUMER and the supplied operator string is blank/null. For OpenAPI consumer tokens Apollo does NOT infer the operator from the principal; the client must pass an explicit operator identifying the user on whose behalf the action is performed.
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/OpenApiOperatorResolver.java:55
public OpenApiOperatorResolver(UserInfoHolder userInfoHolder, UserService userService) {
this.userInfoHolder = userInfoHolder;
this.userService = userService;
}
public String resolve(String operator) {
String authType = UserIdentityContextHolder.getAuthType();
if (UserIdentityConstants.USER.equals(authType)
|| UserIdentityConstants.USER_TOKEN.equals(authType)) {
UserInfo loginUser = userInfoHolder.getUser();
if (loginUser == null || !StringUtils.hasText(loginUser.getUserId())) {
throw new BadRequestException("Current user not found");
}
return loginUser.getUserId();
}
if (UserIdentityConstants.CONSUMER.equals(authType)) {
if (!StringUtils.hasText(operator)) {
throw new BadRequestException("operator should not be null or empty");
}
if (userService.findByUserId(operator) == null) {
throw BadRequestException.userNotExists(operator);
}
return operator;
}
throw new BadRequestException("Unsupported auth type: %s", authType);
}
}
View on GitHub (pinned to d95fc18d11)
Solutions
- Pass a non-blank operator (the userId of the acting user) as a query param or in the request body for CONSUMER-auth requests.
- Ensure the operator value is a real user id — it is also validated against UserService.findByUserId (a follow-up check throws userNotExists otherwise).
- Keep the operator consistent with the user the automation acts on behalf of.
- Add a client-side assertion that operator is non-blank before the call.
Example fix
// before: CONSUMER token, no operator
client.withConsumerToken(token).updateItem(appId, env, cluster, ns, item); // 400
// after: pass explicit operator
client.withConsumerToken(token)
.updateItem(appId, env, cluster, ns, item, operator="alice"); Defensive patterns
Strategy: validation
Validate before calling
// For CONSUMER auth: ensure operator is non-blank and a real user.
if (StringUtils.isBlank(operator)) {
throw new IllegalStateException("operator required for CONSUMER token");
}
// optionally confirm the user exists via a user lookup before the call Type guard
null
Try / catch
try {
client.withConsumerToken(token).someWrite(payload, operator);
} catch (HttpClientErrorException.BadRequest e) {
if (e.getResponseBodyAsString().contains("operator should not be null or empty")) {
operator = resolveDefaultOperator(); client.withConsumerToken(token).someWrite(payload, operator);
}
} Prevention
- Always pass an explicit, non-blank operator for CONSUMER-auth writes.
- Make the operator a valid userId; a follow-up check rejects unknown users.
- Add a client-side non-blank assertion for operator.
When it happens
Trigger: Any OpenAPI write call authenticated with a CONSUMER (OpenAPI) token where no operator query param/body field is provided, or it is empty/whitespace.
Common situations: OpenAPI client omitted the operator query parameter; SDK was upgraded to require operator and the call was not updated; operator field name mismatch between query param and body; trailing whitespace only.
Related errors
- Params(AppId) can not be empty.
- Params(NamespaceName) can not be empty.
- Invalid expires format: %s
- userIds should not be null or empty
- Consumer already exist
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/cf3e6c55ec95d3fb.
Report an issue: GitHub.