pinpoint-apm/pinpoint · error · ResponseStatusException

there should be webhookSendInfoId to delete webhook

Error message

there should be webhookSendInfoId to delete webhook

What it means

The webhook send-info DELETE endpoint in Pinpoint web requires the request body to carry a non-empty webhookSendInfoId. When the body's webhookSendInfoId is missing, null, or blank, the controller rejects the request before calling the service by throwing a 400 BAD_REQUEST ResponseStatusException. This guards against deleting webhook send-info rows without a valid identifier.

Source

Thrown at webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookSendInfoController.java:53

    public WebhookSendInfoController(WebhookSendInfoService webhookSendInfoService) {
        this.webhookSendInfoService = Objects.requireNonNull(webhookSendInfoService, "webhookSendInfoService");
    }


    @PostMapping()
    public WebhookSendInfoResponse insertWebhookSendInfo(@RequestBody WebhookSendInfo webhookSendInfo) {
        if (!StringUtils.hasText(webhookSendInfo.getRuleId()) || !StringUtils.hasText(webhookSendInfo.getWebhookId())) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "there should be ruleId and webhookId to insert webhookSendInfo");
        }
        String webhookSendInfoId = webhookSendInfoService.insertWebhookSendInfo(webhookSendInfo);
        return new WebhookSendInfoResponse(Result.SUCCESS, webhookSendInfoId);
    }

    @DeleteMapping()
    public Response deleteWebhookSendInfo(@RequestBody WebhookSendInfo webhookSendInfo) {
        if (!StringUtils.hasText(webhookSendInfo.getWebhookSendInfoId())) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "there should be webhookSendInfoId to delete webhook");
        }
        webhookSendInfoService.deleteWebhookSendInfo(webhookSendInfo);
        return SimpleResponse.ok();
    }

    @GetMapping()
    public List<WebhookSendInfo> getWebhookSendInfo(@RequestParam(value=WEBHOOK_ID, required=false) String webhookId,
                                                    @RequestParam(value=RULE_ID, required=false) String ruleId) {
        if (!StringUtils.hasText(webhookId) && !StringUtils.hasText(ruleId)) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Either webhookId or ruleId is needed to get webhook send information");
        }

        if (StringUtils.hasText(webhookId)) {
            return webhookSendInfoService.selectWebhookSendInfoByWebhookId(webhookId);
        }

        return webhookSendInfoService.selectWebhookSendInfoByRuleId(ruleId);
    }

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Include a non-empty webhookSendInfoId in the DELETE request body (fetch it first via the GET endpoint if needed).
  2. Verify the JSON field name is exactly webhookSendInfoId so Jackson populates it.
  3. Client-side: check StringUtils.hasText / string truthiness of the id before issuing the DELETE call.
  4. If deleting a webhook, delete its send-info entries using IDs returned when the webhook was created or listed.

Example fix

// before
deleteWebhookSendInfo({ webhookId: 'w-1' });
// after
deleteWebhookSendInfo({ webhookSendInfoId: sendInfo.webhookSendInfoId, webhookId: sendInfo.webhookId, ruleId: sendInfo.ruleId });
Defensive patterns

Strategy: validation

Validate before calling

if (!sendInfo || typeof sendInfo.webhookSendInfoId !== 'string' || sendInfo.webhookSendInfoId.trim() === '') {
  throw new Error('webhookSendInfoId is required to delete webhook send info');
}

Type guard

const hasSendInfoId = (v: unknown): v is { webhookSendInfoId: string } =>
  typeof v === 'object' && v !== null && typeof (v as any).webhookSendInfoId === 'string' && (v as any).webhookSendInfoId.trim().length > 0;

Try / catch

try {
  await deleteWebhookSendInfo(sendInfo);
} catch (e) {
  if (e?.status === 400 && /webhookSendInfoId/.test(e.message)) {
    showError('Cannot delete: webhook send info has no ID. Reload and retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: Sending a DELETE request to the webhook send-info endpoint with an empty JSON body, a body lacking the webhookSendInfoId field, or a body where webhookSendInfoId is "" or whitespace.

Common situations: Frontend code constructs the WebhookSendInfo object from a row that was never persisted (no generated ID yet); API consumers copy a payload shape from the create endpoint and forget the ID; JSON field-name mismatch (e.g. webhookSendInfoID) silently yields null.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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