{"record":{"id":"ec52cbb402de8da4","repo":"pinpoint-apm/pinpoint","slug":"there-should-be-webhooksendinfoid-webhookid-and-r","errorCode":null,"errorMessage":"There should be webhookSendInfoId, webhookId and ruleId to update webhook send information","messagePattern":"There should be webhookSendInfoId, webhookId and ruleId to update webhook send information","errorType":"validation","errorClass":"ResponseStatusException","httpStatus":400,"severity":"error","filePath":"webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookSendInfoController.java","lineNumber":77,"sourceCode":"    @GetMapping()\n    public List<WebhookSendInfo> getWebhookSendInfo(@RequestParam(value=WEBHOOK_ID, required=false) String webhookId,\n                                                    @RequestParam(value=RULE_ID, required=false) String ruleId) {\n        if (!StringUtils.hasText(webhookId) && !StringUtils.hasText(ruleId)) {\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"Either webhookId or ruleId is needed to get webhook send information\");\n        }\n\n        if (StringUtils.hasText(webhookId)) {\n            return webhookSendInfoService.selectWebhookSendInfoByWebhookId(webhookId);\n        }\n\n        return webhookSendInfoService.selectWebhookSendInfoByRuleId(ruleId);\n    }\n\n    @PutMapping()\n    public Response updateWebhookSendInfo(@RequestBody WebhookSendInfo webhookSendInfo) {\n         if (!StringUtils.hasText(webhookSendInfo.getWebhookSendInfoId()) ||\n                !StringUtils.hasText(webhookSendInfo.getWebhookId()) || !StringUtils.hasText(webhookSendInfo.getRuleId())) {\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"There should be webhookSendInfoId, webhookId and ruleId to update webhook send information\");\n        }\n        webhookSendInfoService.updateWebhookSendInfo(webhookSendInfo);\n        return SimpleResponse.ok();\n    }\n}\n","sourceCodeStart":59,"sourceCodeEnd":83,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookSendInfoController.java#L59-L83","documentation":"The PUT endpoint for updating webhook send information requires the request body to contain non-empty webhookSendInfoId, webhookId, and ruleId. If any of the three is missing or blank, the controller throws a 400 BAD_REQUEST ResponseStatusException and skips the update. All three fields are needed to identify the record and its webhook/rule associations.","triggerScenarios":"Sending PUT with a WebhookSendInfo body where webhookSendInfoId, webhookId, or ruleId is null, absent, an empty string, or whitespace.","commonSituations":"Clients send a partially-loaded object (only the fields the user edited); the object was created client-side for a new row and lacks a server-generated webhookSendInfoId; field-name casing mismatches make one property silently undefined after deserialization.","solutions":["Load the existing WebhookSendInfo via GET first and send the complete object with all three fields populated.","Ensure webhookSendInfoId, webhookId, and ruleId are all set on the request body before the PUT.","Client-side: validate all three fields are non-empty strings before calling the update API.","Check JSON field names match the WebhookSendInfo Java properties exactly."],"exampleFix":"// before\nupdateWebhookSendInfo({ webhookSendInfoId: id, webhookId: wid }); // ruleId missing\n// after\nupdateWebhookSendInfo({ webhookSendInfoId: id, webhookId: wid, ruleId: sendInfo.ruleId });","handlingStrategy":"validation","validationCode":"const canUpdate = (info) =>\n  [info?.webhookSendInfoId, info?.webhookId, info?.ruleId].every((v) => typeof v === 'string' && v.trim() !== '');\nif (!canUpdate(webhookSendInfo)) {\n  throw new Error('webhookSendInfoId, webhookId and ruleId are all required to update');\n}","typeGuard":"const isUpdatableSendInfo = (v: unknown): v is { webhookSendInfoId: string; webhookId: string; ruleId: string } =>\n  typeof v === 'object' && v !== null &&\n  ['webhookSendInfoId', 'webhookId', 'ruleId'].every((k) => typeof (v as any)[k] === 'string' && (v as any)[k].trim() !== '');","tryCatchPattern":"try {\n  await updateWebhookSendInfo(info);\n} catch (e) {\n  if (e?.status === 400 && /webhookSendInfoId, webhookId and ruleId/.test(e.message)) {\n    showError('Update failed: reload the record and ensure all fields are present.');\n  } else throw e;\n}","preventionTips":["Fetch the record via GET, mutate it, and PUT the full object rather than a partial patch.","Never send client-constructed objects to update endpoints; only mutate server-fetched records.","Add a form-level check that all three fields are non-empty before submitting.","Keep frontend TypeScript types mirroring the WebhookSendInfo DTO so missing fields fail at compile time."],"tags":["rest-api","bad-request","validation","webhook"],"backgroundTag":"missing-required-argument","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}