{"record":{"id":"415a62378fdb18eb","repo":"apolloconfig/apollo","slug":"release-ids-can-not-be-empty","errorCode":null,"errorMessage":"release ids can not be empty","messagePattern":"release ids can not be empty","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/InstanceController.java","lineNumber":90,"sourceCode":"  public ResponseEntity<Number> getInstanceCountByNamespace(@PathVariable String env,\n      @RequestParam String appId, @RequestParam String clusterName,\n      @RequestParam String namespaceName) {\n\n    int count = instanceService.getInstanceCountByNamespace(appId, Env.valueOf(env), clusterName,\n        namespaceName);\n    return ResponseEntity.ok(new Number(count));\n  }\n\n  @GetMapping(\"/envs/{env}/instances/by-namespace-and-releases-not-in\")\n  public List<InstanceDTO> getByReleasesNotIn(@PathVariable String env, @RequestParam String appId,\n      @RequestParam String clusterName, @RequestParam String namespaceName,\n      @RequestParam String releaseIds) {\n\n    Set<Long> releaseIdSet = RELEASES_SPLITTER.splitToList(releaseIds).stream().map(Long::parseLong)\n        .collect(Collectors.toSet());\n\n    if (CollectionUtils.isEmpty(releaseIdSet)) {\n      throw new BadRequestException(\"release ids can not be empty\");\n    }\n\n    return instanceService.getByReleasesNotIn(Env.valueOf(env), appId, clusterName, namespaceName,\n        releaseIdSet);\n  }\n\n\n}\n","sourceCodeStart":72,"sourceCodeEnd":99,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/InstanceController.java#L72-L99","documentation":"BadRequestException (HTTP 400) from the @Deprecated InstanceController endpoint GET /envs/{env}/instances/by-namespace-and-releases-not-in. releaseIds is split on ',' with omitEmptyStrings+trimResults; if the resulting Set<Long> is empty the handler refuses. Important: a NON-numeric token (e.g. 'abc') throws NumberFormatException from Long::parseLong BEFORE this check, producing a different (500) error instead.","triggerScenarios":"Calling the legacy by-namespace-and-releases-not-in endpoint with releaseIds empty, only commas, or omitted entirely (note releaseIds is a required @RequestParam, so omission yields a 400 'missing parameter' from Spring, not this message).","commonSituations":"Frontend passing an empty selection of releases; building the comma list from an empty array; leftover calls to the deprecated WebAPI after migrating to the OpenAPI equivalents.","solutions":["Pass at least one numeric release id, e.g. releaseIds=12 or releaseIds=12,34.","Migrate to the documented OpenAPI endpoints; this controller is marked @Deprecated.","Strip empty tokens client-side and assert all tokens are numeric (see validationCode) to avoid the NumberFormatException path.","If you genuinely have no releases, short-circuit on the client instead of calling."],"exampleFix":"// before\nGET /envs/DEV/instances/by-namespace-and-releases-not-in?appId=...&releaseIds=\n\n// after\nGET /envs/DEV/instances/by-namespace-and-releases-not-in?appId=...&releaseIds=12,34","handlingStrategy":"validation","validationCode":"// releaseIds: comma-separated, non-empty, all numeric. Matches the server splitter behavior.\nstatic String normalizeReleaseIds(String raw) {\n  if (raw == null) throw new IllegalArgumentException(\"release ids can not be empty\");\n  List<String> parts = Arrays.stream(raw.split(\",\"))\n      .map(String::trim).filter(s -> !s.isEmpty()).collect(Collectors.toList());\n  if (parts.isEmpty()) throw new IllegalArgumentException(\"release ids can not be empty\");\n  for (String p : parts) Long.parseLong(p); // throws -> caller gets a clear client error, not 500\n  return String.join(\",\", parts);\n}","typeGuard":"static boolean isValidReleaseIds(String raw) {\n  if (raw == null) return false;\n  boolean any = false;\n  for (String p : raw.split(\",\")) {\n    String t = p.trim();\n    if (t.isEmpty()) continue;\n    any = true;\n    try { Long.parseLong(t); } catch (NumberFormatException e) { return false; }\n  }\n  return any;\n}","tryCatchPattern":null,"preventionTips":["Never send an empty releaseIds; skip the call if you have none.","Strip blanks and validate numeric tokens client-side to avoid the NumberFormatException 500 path.","Migrate off this @Deprecated controller to the OpenAPI equivalents.","Remember releaseIds is a required query parameter."],"tags":["instance","validation","release","deprecated","bad-request"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}