{"record":{"id":"03580e268bcb1e0d","repo":"xpipe-io/xpipe","slug":"unable-to-parse-store-data-into-valid-store","errorCode":null,"errorMessage":"Unable to parse store data into valid store","messagePattern":"Unable to parse store data into valid store","errorType":"exception","errorClass":"BeaconClientException","httpStatus":400,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/api/StoreAddExchange.java","lineNumber":38,"sourceCode":"import java.util.UUID;\n\npublic class StoreAddExchange extends BeaconInterface<StoreAddExchange.Request> {\n\n    @Override\n    public String getPath() {\n        return \"/store/add\";\n    }\n\n    @Override\n    public List<String> getPathAliases() {\n        return List.of(\"/connection/add\");\n    }\n\n    @Override\n    public Object handle(HttpExchange exchange, Request msg) throws Throwable {\n        var store = JacksonMapper.getDefault().treeToValue(msg.getData(), DataStore.class);\n        if (store == null) {\n            throw new BeaconClientException(\"Unable to parse store data into valid store\");\n        }\n\n        var foundStore = DataStorage.get().getStoreEntryIfPresent(store, false);\n        if (foundStore.isPresent()) {\n            return Response.builder().store(foundStore.get().getUuid()).build();\n        }\n\n        var foundName = DataStorage.get().getStoreEntryIfPresent(msg.getName());\n        if (foundName.isPresent()) {\n            var foundNameStore = foundName.get().getStore();\n            // Only allow updates for the same type of store\n            if (foundNameStore != null && foundNameStore.getClass().equals(store.getClass())) {\n                DataStorage.get().updateEntryStore(foundName.get(), store);\n                return Response.builder().store(foundName.get().getUuid()).build();\n            }\n        }\n\n        if (msg.getCategory() != null","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/api/StoreAddExchange.java#L20-L56","documentation":"StoreAddExchange parses the request's JSON 'data' field into a DataStore via Jackson polymorphic deserialization. If the JSON tree does not deserialize into any known DataStore implementation (or yields null), the handler rejects the request because a store must exist before it can be added.","triggerScenarios":"Calling the store/add beacon endpoint with a 'data' payload that Jackson maps to null or a non-DataStore object — e.g. missing the required 'type'/'category' discriminator fields, misspelled keys, or a JSON shape from a different XPipe version.","commonSituations":"Hand-writing store JSON instead of exporting it from XPipe; API version mismatch where the store format changed; sending the store data under the wrong JSON key.","solutions":["Export the store from XPipe and copy its exact JSON structure into the 'data' field","Ensure the discriminator fields (e.g. the polymorphic type id) are present and spelled correctly","Validate the JSON deserializes: run it through JacksonMapper.getDefault().treeToValue(json, DataStore.class) locally first","Check XPipe version compatibility of the store format"],"exampleFix":"// before\n{\"data\": {\"host\": \"myhost\", \"username\": \"root\"}}\n// after\n{\"data\": {\"type\": \"ssh\", \"remote\": {\"host\": \"myhost\"}, \"username\": \"root\"}}","handlingStrategy":"validation","validationCode":"Object store = JacksonMapper.getDefault().treeToValue(data, DataStore.class);\nif (store == null) throw new IllegalArgumentException(\"store data does not deserialize\");","typeGuard":null,"tryCatchPattern":"try {\n    client.storeAdd(request);\n} catch (BeaconClientException ex) {\n    if (ex.getMessage().contains(\"Unable to parse store data\")) {\n        // fix payload: export JSON from XPipe and reuse\n    } else throw ex;\n}","preventionTips":["Export store JSON from XPipe instead of hand-writing it","Round-trip test the payload with Jackson locally","Keep API and XPipe versions aligned"],"tags":["json","deserialization","store","xpipe"],"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"}