apolloconfig/apollo · error · BadRequestException

AppId not equal. AppId in path = %s, AppId in payload = %s

Error message

AppId not equal. AppId in path = %s, AppId in payload = %s

What it means

Thrown by ClusterController.createCluster when the appId in the URL path does not match the appId field inside the OpenClusterDTO JSON body. Apollo enforces referential integrity between the path parameter and the payload to prevent a caller from accidentally creating a cluster under the wrong app. Maps to HTTP 400 BadRequestException.

Source

Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/ClusterController.java:69

    this.clusterOpenApiService = clusterOpenApiService;
    this.userInfoHolder = userInfoHolder;
    this.unifiedPermissionValidator = unifiedPermissionValidator;
  }

  @Override
  public ResponseEntity<OpenClusterDTO> getCluster(String appId, String clusterName, String env) {
    requireReadApplicationPermissionForUserToken(appId);
    return ResponseEntity.ok(this.clusterOpenApiService.getCluster(appId, env, clusterName));
  }

  @PreAuthorize(value = "@unifiedPermissionValidator.hasCreateClusterPermission(#appId)")
  @ApolloAuditLog(type = OpType.CREATE, name = "Cluster.create")
  @Override
  public ResponseEntity<OpenClusterDTO> createCluster(String appId, String env,
      OpenClusterDTO cluster) {

    if (!Objects.equals(appId, cluster.getAppId())) {
      throw new BadRequestException("AppId not equal. AppId in path = %s, AppId in payload = %s",
          appId, cluster.getAppId());
    }

    String clusterName = cluster.getName();
    requireCreateClusterPermissionForUserToken(appId, env, clusterName);
    String operator = resolveOperator(cluster.getDataChangeCreatedBy());
    cluster.setDataChangeLastModifiedBy(operator);
    cluster.setDataChangeCreatedBy(operator);

    RequestPrecondition.checkArguments(!StringUtils.isContainEmpty(clusterName, operator),
        "name and dataChangeCreatedBy should not be null or empty");

    if (!InputValidator.isValidClusterNamespace(clusterName)) {
      throw BadRequestException
          .invalidClusterNameFormat(InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE);
    }

    return ResponseEntity.ok(this.clusterOpenApiService.createCluster(env, cluster, operator));

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Make the appId in the JSON body identical to the appId in the URL path — set cluster.setAppId(appId) before sending.
  2. Use a single source variable for appId in client code to populate both the path and the body.
  3. Add a client-side assertion: Objects.equals(pathAppId, body.getAppId()) before the HTTP call.

Example fix

// before — path and body appId can diverge
String urlAppId = "someApp";
OpenClusterDTO cluster = new OpenClusterDTO();
cluster.setAppId(config.getString("cluster.appId")); // different source!
cluster.setName("prod-cluster");
client.post("/openapi/v1/envs/PROD/apps/" + urlAppId + "/clusters", cluster);

// after — single source of truth for appId
String appId = "someApp";
OpenClusterDTO cluster = new OpenClusterDTO();
cluster.setAppId(appId);
cluster.setName("prod-cluster");
client.post("/openapi/v1/envs/PROD/apps/" + appId + "/clusters", cluster);
Defensive patterns

Strategy: validation

Validate before calling

// Validate path appId matches body appId before the HTTP call
if (!Objects.equals(pathAppId, clusterBody.getAppId())) {
    throw new IllegalArgumentException(
        String.format("AppId mismatch: path=%s, body=%s", pathAppId, clusterBody.getAppId()));
}
// Or simply sync them:
clusterBody.setAppId(pathAppId);

Prevention

When it happens

Trigger: POST /openapi/v1/envs/{env}/apps/appA/clusters where the JSON body contains {"appId":"appB","name":"myCluster"}. The Objects.equals(appId, cluster.getAppId()) guard catches the mismatch.

Common situations: Copy-pasting a request body template from another app without updating the appId field. Automation scripts that construct the path from one variable and the body from another, where the two variables diverge due to a bug.

Related errors


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