{"record":{"id":"6d2349b336458486","repo":"xpipe-io/xpipe","slug":"parent-category-with-id-msg-getparent-do","errorCode":null,"errorMessage":"Parent category with id \" + msg.getParent() + \" does not exist","messagePattern":"Parent category with id \" \\+ msg\\.getParent\\(\\) \\+ \" does not exist","errorType":"exception","errorClass":"BeaconClientException","httpStatus":400,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/beacon/api/CategoryAddExchange.java","lineNumber":26,"sourceCode":"import com.sun.net.httpserver.HttpExchange;\nimport lombok.Builder;\nimport lombok.NonNull;\nimport lombok.Value;\nimport lombok.extern.jackson.Jacksonized;\n\nimport java.util.UUID;\n\npublic class CategoryAddExchange extends BeaconInterface<CategoryAddExchange.Request> {\n\n    @Override\n    public String getPath() {\n        return \"/category/add\";\n    }\n\n    @Override\n    public Object handle(HttpExchange exchange, Request msg) throws Throwable {\n        if (DataStorage.get().getStoreCategoryIfPresent(msg.getParent()).isEmpty()) {\n            throw new BeaconClientException(\"Parent category with id \" + msg.getParent() + \" does not exist\");\n        }\n\n        var found = DataStorage.get().getStoreCategories().stream()\n                .filter(dataStoreCategory -> msg.getParent().equals(dataStoreCategory.getParentCategory())\n                        && msg.getName().equals(dataStoreCategory.getName()))\n                .findAny();\n        if (found.isPresent()) {\n            return Response.builder().category(found.get().getUuid()).build();\n        }\n\n        var cat = DataStoreCategory.createNew(msg.getParent(), msg.getName());\n        DataStorage.get().addStoreCategory(cat);\n        return Response.builder().category(cat.getUuid()).build();\n    }\n\n    @Override\n    public Object getSynchronizationObject() {\n        return DataStorage.get();","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/beacon/api/CategoryAddExchange.java#L8-L44","documentation":"CategoryAddExchange handles /category/add. Before creating a category it checks that the parent category id (msg.getParent()) exists in DataStorage; if not, it throws BeaconClientException stating the parent category does not exist. Clients must reference an existing (e.g. built-in root) category id.","triggerScenarios":"Passing a null/empty/garbage parent id; referencing a category deleted earlier; using a category UUID from a different XPipe installation or after a storage reset; hard-coded ids that changed between versions.","commonSituations":"Automation copying category ids between machines; scripts written before a storage migration; typos in UUIDs; trying to create top-level categories without using the built-in root category id.","solutions":["Fetch the valid parent id first (e.g. query existing store categories or use the built-in root category's UUID) instead of hard-coding it.","Create/ensure the parent category exists before adding the child category.","Validate msg.getParent() against DataStorage.get().getStoreCategoryIfPresent(parent) on the client side before calling add.","If ids were persisted, migrate them after storage resets or version upgrades rather than reusing stale UUIDs."],"exampleFix":"// before\nvar req = new CategoryAddExchange.Request();\nreq.setParent(UUID.fromString(\"0000-...\")); // non-existent parent\n// after\nvar rootId = DataStorage.get().getDefaultStoreCategory(true).getUuid();\nvar req = new CategoryAddExchange.Request();\nreq.setParent(rootId); // use a verified existing parent","handlingStrategy":"validation","validationCode":"// verify parent exists before adding\nboolean parentExists = client.getStoreCategories().stream()\n    .anyMatch(c -> c.getUuid().equals(parentId));","typeGuard":"boolean isExistingCategory(UUID parentId, List<DataStoreCategory> cats) {\n    return parentId != null && cats.stream().anyMatch(c -> parentId.equals(c.getUuid()));\n}","tryCatchPattern":"try {\n    client.performRequest(addCategoryRequest);\n} catch (BeaconClientException e) {\n    if (e.getMessage().contains(\"does not exist\")) {\n        UUID root = getDefaultRootCategoryId();\n        addCategoryRequest.setParent(root);\n        client.performRequest(addCategoryRequest);\n    }\n}","preventionTips":["Fetch parent ids from the daemon's category list instead of hard-coding UUIDs","Re-resolve ids after storage resets, migrations, or version upgrades","When creating nested categories, create parents first and use returned ids"],"tags":["beacon","category","stale-uuid","missing-parent"],"backgroundTag":"entity-not-found","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}