xpipe-io/xpipe · error · BeaconClientException

Category with id " + msg.getCategory() + " does not exist

Error message

Category with id " + msg.getCategory() + " does not exist

What it means

When adding a store with an explicit category UUID, StoreAddExchange verifies the category exists in DataStorage. If the supplied category UUID does not match any known store category, the request is rejected so the store is not created under a dangling category.

Source

Thrown at app/src/main/java/io/xpipe/app/beacon/api/StoreAddExchange.java:60

        if (foundStore.isPresent()) {
            return Response.builder().store(foundStore.get().getUuid()).build();
        }

        var foundName = DataStorage.get().getStoreEntryIfPresent(msg.getName());
        if (foundName.isPresent()) {
            var foundNameStore = foundName.get().getStore();
            // Only allow updates for the same type of store
            if (foundNameStore != null && foundNameStore.getClass().equals(store.getClass())) {
                DataStorage.get().updateEntryStore(foundName.get(), store);
                return Response.builder().store(foundName.get().getUuid()).build();
            }
        }

        if (msg.getCategory() != null
                && DataStorage.get()
                        .getStoreCategoryIfPresent(msg.getCategory())
                        .isEmpty()) {
            throw new BeaconClientException("Category with id " + msg.getCategory() + " does not exist");
        }

        var entry = DataStoreEntry.createNew(msg.getName(), store);
        if (msg.getCategory() != null) {
            entry.setCategoryUuid(msg.getCategory());
        }
        try {
            DataStorage.get().addStoreEntryInProgress(entry);
            if (msg.getValidate()) {
                entry.validateOrThrow();
            } else {
                store.checkComplete();
            }
        } catch (Throwable ex) {
            if (ex instanceof ValidationException) {
                ErrorEventFactory.expected(ex);
            } else if (ex instanceof StackOverflowError) {
                // Cycles in connection graphs can fail hard but are expected

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Look up the correct category UUID via the store/category beacon listing API and use that value
  2. Omit the 'category' field to add the store to the default category
  3. Create the category first, then add the store referencing its new UUID
  4. Validate the UUID client-side before the call

Example fix

// before
client.storeAdd(name, data, "d1e0...possibly-deleted-uuid");
// after
var cat = DataStorage.get().getStoreCategoryIfPresent(uuid);
if (cat.isEmpty()) { uuid = DataStorage.DEFAULT_CATEGORY_UUID; }
client.storeAdd(name, data, uuid);
Defensive patterns

Strategy: validation

Validate before calling

if (categoryUuid != null &&
    DataStorage.get().getStoreCategoryIfPresent(UUID.fromString(categoryUuid)).isEmpty()) {
    throw new IllegalArgumentException("category does not exist");
}

Try / catch

try {
    client.storeAdd(request);
} catch (BeaconClientException ex) {
    if (ex.getMessage().contains("does not exist")) {
        request.setCategory(null); // retry with default category
    } else throw ex;
}

Prevention

When it happens

Trigger: Calling store/add with a non-null 'category' field whose UUID is not a registered store category (typo, store from another machine, category deleted, or sending an entry UUID instead of a category UUID).

Common situations: Hard-coding a category UUID from a different XPipe installation; category removed after scripts were written; confusing connection UUIDs with category UUIDs.

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/013345fcc2acf431. Report an issue: GitHub.