apolloconfig/apollo · error · BadRequestException

operator should not be null or empty

Error message

operator should not be null or empty

What it means

Thrown by ConsumerService.validateOperator when the operator string is null, empty, or contains only whitespace. This private method is called at the top of every role-assignment and consumer-role-creation method. Apollo requires an operator identifier for audit/data-change tracking (DataChangeCreatedBy / DataChangeLastModifiedBy fields). Results in HTTP 400.

Source

Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/service/ConsumerService.java:419

        KEY_JOINER.join(consumerAppId, TIMESTAMP_FORMAT.format(generationTime), consumerTokenSalt),
        Charsets.UTF_8).toString();
  }

  ConsumerRole createConsumerRole(Long consumerId, Long roleId, String operator) {
    validateOperator(operator);
    ConsumerRole consumerRole = new ConsumerRole();

    consumerRole.setConsumerId(consumerId);
    consumerRole.setRoleId(roleId);
    consumerRole.setDataChangeCreatedBy(operator);
    consumerRole.setDataChangeLastModifiedBy(operator);

    return consumerRole;
  }

  private void validateOperator(String operator) {
    if (Strings.isNullOrEmpty(operator) || operator.trim().isEmpty()) {
      throw new BadRequestException("operator should not be null or empty");
    }
  }

  public Set<String> findAppIdsAuthorizedByConsumerId(long consumerId) {
    List<ConsumerRole> consumerRoles = this.findConsumerRolesByConsumerId(consumerId);
    List<Long> roleIds =
        consumerRoles.stream().map(ConsumerRole::getRoleId).collect(Collectors.toList());

    return this.findAppIdsByRoleIds(roleIds);
  }

  private List<ConsumerRole> findConsumerRolesByConsumerId(long consumerId) {
    return this.consumerRoleRepository.findByConsumerId(consumerId);
  }

  private Set<String> findAppIdsByRoleIds(List<Long> roleIds) {
    Iterable<Role> roleIterable = this.roleRepository.findAllById(roleIds);

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Ensure the operator parameter is a non-blank user ID (e.g., the logged-in user's userId) before calling the service method.
  2. If the operator is derived from the request context, validate it early in the controller layer and return a clear error.
  3. For automation/API clients, always include the operator field in the request payload.

Example fix

// before
consumerService.assignAppRoleToConsumer(token, appId, null);

// after
String operator = resolveOperator(request.getOperator());
if (operator == null || operator.trim().isEmpty()) {
    throw new BadRequestException("operator should not be null or empty");
}
consumerService.assignAppRoleToConsumer(token, appId, operator);
Defensive patterns

Strategy: validation

Validate before calling

// Validate operator before calling ConsumerService methods
public static String requireOperator(String operator) {
    if (operator == null || operator.trim().isEmpty()) {
        throw new IllegalArgumentException("operator must be a non-blank user ID");
    }
    return operator.trim();
}

Prevention

When it happens

Trigger: Calling any ConsumerService method that takes an operator parameter (assignCreateApplicationRoleToConsumer, assignManageUsersRoleToConsumer, assignAppRoleToConsumer, assignNamespaceRoleToConsumer, createConsumerRole) with operator = null, operator = "", or operator = " ".

Common situations: An API client omits the operator field from the request body or query parameter. A service-layer caller passes null because the operator was derived from a context holder that was not populated. A test or integration script calls the service directly without setting an operator.

Related errors


AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14). Data as JSON: /api/errors/c2906b9f81e79a78. Report an issue: GitHub.