{"record":{"id":"092e7b3d5ca27abe","repo":"apolloconfig/apollo","slug":"appid-not-equal-appid-in-path-s-appid-in-payl","errorCode":null,"errorMessage":"AppId not equal. AppId in path = %s, AppId in payload = %s","messagePattern":"AppId not equal\\. AppId in path = (.+?), AppId in payload = (.+?)","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/ClusterController.java","lineNumber":69,"sourceCode":"    this.clusterOpenApiService = clusterOpenApiService;\n    this.userInfoHolder = userInfoHolder;\n    this.unifiedPermissionValidator = unifiedPermissionValidator;\n  }\n\n  @Override\n  public ResponseEntity<OpenClusterDTO> getCluster(String appId, String clusterName, String env) {\n    requireReadApplicationPermissionForUserToken(appId);\n    return ResponseEntity.ok(this.clusterOpenApiService.getCluster(appId, env, clusterName));\n  }\n\n  @PreAuthorize(value = \"@unifiedPermissionValidator.hasCreateClusterPermission(#appId)\")\n  @ApolloAuditLog(type = OpType.CREATE, name = \"Cluster.create\")\n  @Override\n  public ResponseEntity<OpenClusterDTO> createCluster(String appId, String env,\n      OpenClusterDTO cluster) {\n\n    if (!Objects.equals(appId, cluster.getAppId())) {\n      throw new BadRequestException(\"AppId not equal. AppId in path = %s, AppId in payload = %s\",\n          appId, cluster.getAppId());\n    }\n\n    String clusterName = cluster.getName();\n    requireCreateClusterPermissionForUserToken(appId, env, clusterName);\n    String operator = resolveOperator(cluster.getDataChangeCreatedBy());\n    cluster.setDataChangeLastModifiedBy(operator);\n    cluster.setDataChangeCreatedBy(operator);\n\n    RequestPrecondition.checkArguments(!StringUtils.isContainEmpty(clusterName, operator),\n        \"name and dataChangeCreatedBy should not be null or empty\");\n\n    if (!InputValidator.isValidClusterNamespace(clusterName)) {\n      throw BadRequestException\n          .invalidClusterNameFormat(InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE);\n    }\n\n    return ResponseEntity.ok(this.clusterOpenApiService.createCluster(env, cluster, operator));","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/ClusterController.java#L51-L87","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make the appId in the JSON body identical to the appId in the URL path — set cluster.setAppId(appId) before sending.","Use a single source variable for appId in client code to populate both the path and the body.","Add a client-side assertion: Objects.equals(pathAppId, body.getAppId()) before the HTTP call."],"exampleFix":"// before — path and body appId can diverge\nString urlAppId = \"someApp\";\nOpenClusterDTO cluster = new OpenClusterDTO();\ncluster.setAppId(config.getString(\"cluster.appId\")); // different source!\ncluster.setName(\"prod-cluster\");\nclient.post(\"/openapi/v1/envs/PROD/apps/\" + urlAppId + \"/clusters\", cluster);\n\n// after — single source of truth for appId\nString appId = \"someApp\";\nOpenClusterDTO cluster = new OpenClusterDTO();\ncluster.setAppId(appId);\ncluster.setName(\"prod-cluster\");\nclient.post(\"/openapi/v1/envs/PROD/apps/\" + appId + \"/clusters\", cluster);","handlingStrategy":"validation","validationCode":"// Validate path appId matches body appId before the HTTP call\nif (!Objects.equals(pathAppId, clusterBody.getAppId())) {\n    throw new IllegalArgumentException(\n        String.format(\"AppId mismatch: path=%s, body=%s\", pathAppId, clusterBody.getAppId()));\n}\n// Or simply sync them:\nclusterBody.setAppId(pathAppId);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a single variable for appId and derive both the URL path and the body field from it.","Add a pre-send assertion in API client wrappers that path and body appIds match.","In integration tests, parametrize both path and body appId from the same source."],"tags":["validation","openapi","cluster","bad-request","http-400","payload-mismatch"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}