xpipe-io/xpipe · error · BeaconClientException

Parent category with id " + msg.getParent() + " does not exi

Error message

Parent category with id " + msg.getParent() + " does not exist

What it means

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.

Source

Thrown at app/src/main/java/io/xpipe/app/beacon/api/CategoryAddExchange.java:26

import com.sun.net.httpserver.HttpExchange;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;

import java.util.UUID;

public class CategoryAddExchange extends BeaconInterface<CategoryAddExchange.Request> {

    @Override
    public String getPath() {
        return "/category/add";
    }

    @Override
    public Object handle(HttpExchange exchange, Request msg) throws Throwable {
        if (DataStorage.get().getStoreCategoryIfPresent(msg.getParent()).isEmpty()) {
            throw new BeaconClientException("Parent category with id " + msg.getParent() + " does not exist");
        }

        var found = DataStorage.get().getStoreCategories().stream()
                .filter(dataStoreCategory -> msg.getParent().equals(dataStoreCategory.getParentCategory())
                        && msg.getName().equals(dataStoreCategory.getName()))
                .findAny();
        if (found.isPresent()) {
            return Response.builder().category(found.get().getUuid()).build();
        }

        var cat = DataStoreCategory.createNew(msg.getParent(), msg.getName());
        DataStorage.get().addStoreCategory(cat);
        return Response.builder().category(cat.getUuid()).build();
    }

    @Override
    public Object getSynchronizationObject() {
        return DataStorage.get();

View on GitHub (pinned to d85ca821ba)

Solutions

  1. 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.
  2. Create/ensure the parent category exists before adding the child category.
  3. Validate msg.getParent() against DataStorage.get().getStoreCategoryIfPresent(parent) on the client side before calling add.
  4. If ids were persisted, migrate them after storage resets or version upgrades rather than reusing stale UUIDs.

Example fix

// before
var req = new CategoryAddExchange.Request();
req.setParent(UUID.fromString("0000-...")); // non-existent parent
// after
var rootId = DataStorage.get().getDefaultStoreCategory(true).getUuid();
var req = new CategoryAddExchange.Request();
req.setParent(rootId); // use a verified existing parent
Defensive patterns

Strategy: validation

Validate before calling

// verify parent exists before adding
boolean parentExists = client.getStoreCategories().stream()
    .anyMatch(c -> c.getUuid().equals(parentId));

Type guard

boolean isExistingCategory(UUID parentId, List<DataStoreCategory> cats) {
    return parentId != null && cats.stream().anyMatch(c -> parentId.equals(c.getUuid()));
}

Try / catch

try {
    client.performRequest(addCategoryRequest);
} catch (BeaconClientException e) {
    if (e.getMessage().contains("does not exist")) {
        UUID root = getDefaultRootCategoryId();
        addCategoryRequest.setParent(root);
        client.performRequest(addCategoryRequest);
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/6d2349b336458486. Report an issue: GitHub.