{"record":{"id":"4c72365a8fb541e0","repo":"xpipe-io/xpipe","slug":"couldn-t-parse-client-error-message","errorCode":null,"errorMessage":"Couldn't parse client error message","messagePattern":"Couldn't parse client error message","errorType":"exception","errorClass":"BeaconConnectorException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/BeaconClient.java","lineNumber":132,"sourceCode":"        if (AppProperties.get().isPrintBeaconMessages()) {\n            System.out.println(\n                    \"Sending request to server of type \" + req.getClass().getName());\n        }\n\n        return performRequest(prov.get(), node.toPrettyString());\n    }\n\n    private Optional<BeaconClientErrorResponse> parseClientError(HttpResponse<String> response)\n            throws BeaconConnectorException {\n        if (response.statusCode() < 400 || response.statusCode() > 499) {\n            return Optional.empty();\n        }\n\n        try {\n            var v = JacksonMapper.getDefault().readValue(response.body(), BeaconClientErrorResponse.class);\n            return Optional.of(v);\n        } catch (Exception ex) {\n            throw new BeaconConnectorException(\"Couldn't parse client error message\", ex);\n        }\n    }\n\n    private Optional<BeaconServerErrorResponse> parseServerError(HttpResponse<String> response)\n            throws BeaconConnectorException {\n        if (response.statusCode() < 500 || response.statusCode() > 599) {\n            return Optional.empty();\n        }\n\n        try {\n            var v = JacksonMapper.getDefault().readValue(response.body(), BeaconServerErrorResponse.class);\n            return Optional.of(v);\n        } catch (Exception ex) {\n            throw new BeaconConnectorException(\"Couldn't parse client error message\", ex);\n        }\n    }\n}\n","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/BeaconClient.java#L114-L150","documentation":"When the beacon server responds with a 4xx status, the client tries to decode the body into BeaconClientErrorResponse to surface the server-side error message. If the body cannot be parsed as that JSON shape, this BeaconConnectorException replaces the original error information.","triggerScenarios":"A 4xx response body is not valid JSON or does not match BeaconClientErrorResponse's fields (e.g. an HTML auth-failure page, a plain-text error from a proxy, or a schema drift between client and daemon error formats).","commonSituations":"API key / auth rejection returning a non-standard body; a load balancer or proxy intercepting 4xx responses; version mismatch changing the error payload layout; hitting a non-beacon HTTP endpoint by mistake.","solutions":["Print response.body() (or enable printBeaconMessages) to inspect what the server actually returned on the 4xx.","Ensure the client is authenticated and calling the intended beacon endpoint so real JSON error bodies are returned.","Match client and daemon versions so the error response schema matches BeaconClientErrorResponse.","Handle parse failure as an opaque HTTP 4xx failure instead of expecting the structured message."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// authenticate and target the right endpoint first\nboolean authed = apiKey != null && endpointPath.startsWith(\"/\");","typeGuard":null,"tryCatchPattern":"try {\n    return client.performRequest(req);\n} catch (BeaconConnectorException e) {\n    // 4xx body was not a parseable BeaconClientErrorResponse; treat as generic HTTP failure\n    LOG.warn(\"Beacon returned client error with unparseable body\", e);\n    throw new HttpRequestFailed(req, e);\n}","preventionTips":["Send valid credentials so the daemon returns its standard JSON error bodies","Verify the endpoint URL points at the beacon server, not a proxy page","Match client/daemon versions for stable error payload schemas"],"tags":["http","json","error-response","beacon"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}