pinpoint-apm/pinpoint · error · ResponseStatusException

Either webhookId or ruleId is needed to get webhook send inf

Error message

Either webhookId or ruleId is needed to get webhook send information

What it means

The GET endpoint for webhook send information supports two optional query parameters, webhookId and ruleId, but requires at least one of them. If both are absent or blank the controller throws a 400 BAD_REQUEST ResponseStatusException, because it cannot determine which send-info records to select.

Source

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

        }
        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);
    }

    @PutMapping()
    public Response updateWebhookSendInfo(@RequestBody WebhookSendInfo webhookSendInfo) {
         if (!StringUtils.hasText(webhookSendInfo.getWebhookSendInfoId()) ||
                !StringUtils.hasText(webhookSendInfo.getWebhookId()) || !StringUtils.hasText(webhookSendInfo.getRuleId())) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "There should be webhookSendInfoId, webhookId and ruleId to update webhook send information");
        }
        webhookSendInfoService.updateWebhookSendInfo(webhookSendInfo);
        return SimpleResponse.ok();
    }

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Pass webhookId as a query parameter to fetch send-info for a specific webhook: GET ?webhookId=<id>.
  2. Pass ruleId instead when filtering by rule: GET ?ruleId=<id>.
  3. Client-side: only call the endpoint after validating that at least one of webhookId/ruleId is non-empty.
  4. If listing all is intended, use the webhook or rule list endpoints and iterate.

Example fix

// before
const list = await api.get('/webhookSendInfo');
// after
const list = await api.get(`/webhookSendInfo?webhookId=${encodeURIComponent(webhookId)}`);
Defensive patterns

Strategy: validation

Validate before calling

if (!(webhookId?.trim() || ruleId?.trim())) {
  throw new Error('Either webhookId or ruleId is required to fetch webhook send information');
}

Type guard

const hasWebhookFilter = (q: { webhookId?: string; ruleId?: string }): q is { webhookId: string } | { ruleId: string } =>
  Boolean(q.webhookId?.trim() || q.ruleId?.trim());

Try / catch

try {
  const list = await fetchWebhookSendInfo({ webhookId });
} catch (e) {
  if (e?.status === 400) {
    console.warn('Missing webhookId/ruleId filter; skipping webhook send info fetch');
    return [];
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling GET on the webhook send-info endpoint with no query parameters, or with both webhookId= and ruleId= present but empty/whitespace.

Common situations: Clients build the URL from state where both filter values are undefined/empty strings (e.g. a cleared search form); a query-string builder drops falsy params entirely; consumers expect an unfiltered list endpoint but this one intentionally has no list-all mode.

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/d4828bcc456dc650. Report an issue: GitHub.