pinpoint-apm/pinpoint · warning · ResponseStatusException

there is not ruleId to delete alarm rule

Error message

there is not ruleId to delete alarm rule

What it means

DELETE /alarmRule requires the rule's ID in the request body; when rule.getRuleId() is empty the controller refuses the delete with HTTP 400, because without a ruleId the service cannot identify which rule to remove.

Source

Thrown at web/src/main/java/com/navercorp/pinpoint/web/authorization/controller/AlarmController.java:77

    public AlarmController(AlarmService alarmService) {
        this.alarmService = Objects.requireNonNull(alarmService, "alarmService");
    }

    @PreAuthorize("@naverPermissionEvaluator.hasAlarmPermission(#serviceName.getName(), #rule.getApplicationName(), T(com.navercorp.pinpoint.web.security.PermissionChecker).PERMISSION_ALARM_EDIT_ALARM_ONLY_MANAGER)")
    @PostMapping
    public AlarmResponse insertRule(@ServiceParam ServiceName serviceName, @RequestBody Rule rule) {
        if (Rule.isRuleInvalidForPost(rule)) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "there is not applicationId/checkerName/userGroupId/threashold to insert alarm rule");
        }
        final String ruleId = alarmService.insertRule(rule);
        return new AlarmResponse(Result.SUCCESS, ruleId);
    }

    @PreAuthorize("@naverPermissionEvaluator.hasAlarmPermission(#serviceName.getName(), #rule.getApplicationName(), T(com.navercorp.pinpoint.web.security.PermissionChecker).PERMISSION_ALARM_EDIT_ALARM_ONLY_MANAGER)")
    @DeleteMapping
    public Response deleteRule(@ServiceParam ServiceName serviceName, @RequestBody Rule rule) {
        if (StringUtils.isEmpty(rule.getRuleId())) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "there is not ruleId to delete alarm rule");
        }
        alarmService.deleteRule(rule);
        return SimpleResponse.ok();
    }

    @GetMapping(params = USER_GROUP_ID_PARAMS)
    public List<Rule> getRulesByUserGroup(@ServiceParam ServiceName serviceName, @RequestParam(value = USER_GROUP_ID_PARAMS) @NotBlank String userGroupId) {
        return alarmService.selectRuleByUserGroupId(userGroupId);
    }

    @GetMapping(params = APPLICATION_ID_PARAMS)
    public List<Rule> getRulesByApplication(@ServiceParam ServiceName serviceName, @RequestParam(value = APPLICATION_ID_PARAMS) @NotBlank String applicationName) {
        return alarmService.selectRuleByApplicationName(applicationName);
    }

    @PreAuthorize("@naverPermissionEvaluator.hasAlarmPermission(#serviceName.getName(), #rule.getApplicationName(), T(com.navercorp.pinpoint.web.security.PermissionChecker).PERMISSION_ALARM_EDIT_ALARM_ONLY_MANAGER)")
    @PutMapping
    public Response updateRule(@ServiceParam ServiceName serviceName, @RequestBody Rule rule) {

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Fetch the rule list (GET /alarmRule) and copy its ruleId into the delete body
  2. Ensure ruleId is a non-empty string in the DELETE JSON payload
  3. If the rule was recreated, re-fetch its ID rather than reusing a cached one

Example fix

// before
DELETE /alarmRule {"applicationName":"myApp","checkerName":"ERROR_RATE"}
// after
DELETE /alarmRule {"ruleId":"1723456789_0","applicationName":"myApp","checkerName":"ERROR_RATE"}
Defensive patterns

Strategy: validation

Validate before calling

if (!rule.ruleId) throw new Error("ruleId is required to delete an alarm rule");

Type guard

function hasRuleId(r) { return r != null && typeof r.ruleId === 'string' && r.ruleId.length > 0; }

Try / catch

try { ... } catch (HttpClientErrorException e) { if (e.getStatusCode().value() == 400) { /* re-fetch ruleId then retry */ } else { throw e; } }

Prevention

When it happens

Trigger: Sending a DELETE /alarmRule request with a Rule JSON body lacking the ruleId field or containing an empty string.

Common situations: Clients that built the delete body from a rule object fetched before rules were re-created (stale/empty ruleId); scripts that only pass applicationName and checkerName.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/2515ae98cd5dac52. Report an issue: GitHub.