{"record":{"id":"bc518cbf348741d4","repo":"ory/kratos","slug":"webhook-response-could-not-be-unmarshalled-properl","errorCode":null,"errorMessage":"webhook response could not be unmarshalled properly from JSON","messagePattern":"webhook response could not be unmarshalled properly from JSON","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"selfservice/hook/web_hook.go","lineNumber":471,"sourceCode":"}\n\nfunc parseWebhookResponse(resp *http.Response, id *identity.Identity) (err error) {\n\tif resp == nil {\n\t\treturn errors.Errorf(\"empty response provided from the webhook\")\n\t}\n\n\tif resp.StatusCode == http.StatusOK {\n\t\ttype localIdentity identity.Identity\n\t\tvar hookResponse struct {\n\t\t\tIdentity *localIdentity `json:\"identity\"`\n\t\t}\n\t\t// io.ReadAll is safe, because resp.Body is already a limited reader.\n\t\tbody, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"webhook response body could not be read\")\n\t\t}\n\t\tif err = json.Unmarshal(body, &hookResponse); err != nil {\n\t\t\treturn errors.Wrap(err, \"webhook response could not be unmarshalled properly from JSON\")\n\t\t}\n\n\t\tif hookResponse.Identity == nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tif len(hookResponse.Identity.Traits) > 0 {\n\t\t\tid.Traits = hookResponse.Identity.Traits\n\t\t}\n\n\t\tif len(hookResponse.Identity.SchemaID) > 0 {\n\t\t\tid.SchemaID = hookResponse.Identity.SchemaID\n\t\t}\n\n\t\tif len(hookResponse.Identity.State) > 0 {\n\t\t\tid.State = hookResponse.Identity.State\n\t\t}\n","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/selfservice/hook/web_hook.go#L453-L489","documentation":"The webhook responded with 200 and its body was read successfully, but json.Unmarshal could not decode it into the expected {identity: ...} structure. The upstream webhook returned a body that is not valid JSON for the contract kratos expects on success responses.","triggerScenarios":"Thrown at selfservice/hook/web_hook.go:471 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Make the webhook return valid JSON, or an empty body with a non-200 status if it has nothing to modify","Ensure a 200 response wraps any identity modifications in an {\"identity\": {...}} envelope","Check for HTML error pages or plain-text bodies being served instead of JSON"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}