{"record":{"id":"f1b91759ac18abb1","repo":"pinpoint-apm/pinpoint","slug":"missing-arguments-webhook-id-webhook-url-applic","errorCode":null,"errorMessage":"Missing arguments: webhook.id, webhook.url, applicationId/serviceName","messagePattern":"Missing arguments: webhook\\.id, webhook\\.url, applicationId/serviceName","errorType":"validation","errorClass":"ResponseStatusException","httpStatus":400,"severity":"warning","filePath":"webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookController.java","lineNumber":101,"sourceCode":"\n        if (StringUtils.hasText(ruleId)) {\n            return webhookService.selectWebhookByRuleId(ruleId);\n        }\n\n        if (StringUtils.hasText(applicationName)) {\n            return webhookService.selectWebhookByApplicationName(applicationName);\n        }\n\n        return webhookService.selectWebhookByServiceName(serviceName);\n    }\n\n    @PutMapping()\n    public Response updateWebhook(@RequestBody Webhook webhook) {\n\n        if (!StringUtils.hasText(webhook.getWebhookId()) || !StringUtils.hasText(webhook.getUrl()) ||\n                !(StringUtils.hasText(webhook.getApplicationName()) || StringUtils.hasText(webhook.getServiceName()))) {\n            logger.info(\"Missing arguments: webhook.id, webhook.url, applicationId/serviceName\");\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"Missing arguments: webhook.id, webhook.url, applicationId/serviceName\");\n        }\n\n        try {\n            validateURL(webhook);\n        } catch (IllegalArgumentException e) {\n            logger.info(\"Invalid argument: webhook.url\");\n            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"Invalid argument: webhook.url\");\n        }\n\n        webhookService.updateWebhook(webhook);\n        return SimpleResponse.ok();\n    }\n\n    private void validateURL(Webhook webhook) {\n        webhook.setUrl(WebhookUrlValidator.validate(webhook.getUrl()));\n    }\n}\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookController.java#L83-L119","documentation":"WebhookController.updateWebhook validates that the PUT body supplies a webhookId, a url, and an application identity (applicationName or serviceName). If any of these is missing/empty, it throws HTTP 400 before performing URL validation or the update, since an update without the id cannot target a row and without url/application binding would be meaningless.","triggerScenarios":"PUT /webhook with body missing webhookId, missing url, or missing both applicationName and serviceName; empty-string values also trigger it; wrong key casing leaves the POJO fields null.","commonSituations":"Clients echoing back a webhook object read from an API variant that omits url; partial-update attempts sending only changed fields (the API requires full object); renames where serviceName was dropped from the payload.","solutions":["Send the complete Webhook object: webhookId, url, and either applicationName or serviceName all non-empty","Fetch the current webhook via GET /webhook and merge your change before PUTting it back","Verify URL starts with a valid scheme since validateURL runs immediately after this check","Confirm JSON key names/casing match the Webhook DTO fields"],"exampleFix":"// before\n{\"webhookId\":\"abc123\",\"url\":\"https://hooks.example.com/x\"}\n// after\n{\"webhookId\":\"abc123\",\"url\":\"https://hooks.example.com/x\",\"serviceName\":\"myService\"}","handlingStrategy":"validation","validationCode":"function canUpdateWebhook(w) { return Boolean(w && w.webhookId?.trim() && w.url?.trim() && (w.applicationName?.trim() || w.serviceName?.trim())); }","typeGuard":"function isCompleteWebhook(w) { return typeof w.webhookId === 'string' && w.webhookId.length > 0 && typeof w.url === 'string' && w.url.length > 0 && (typeof w.applicationName === 'string' || typeof w.serviceName === 'string'); }","tryCatchPattern":"try { await api.updateWebhook(body); } catch (e) { if (e.response?.status === 400 && e.response?.data?.message?.includes('Missing arguments')) { /* re-fetch webhook and merge full object */ } throw e; }","preventionTips":["Implement update as read-modify-write: GET the webhook, mutate one field, PUT the whole object","Never send partial JSON bodies to this endpoint — it is not a PATCH API","Centralize a buildWebhookPayload() helper that asserts required fields","Keep field names/casing in sync with the server DTO when it changes"],"tags":["http-400","rest-api","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"}