linshenkx/prompt-optimizer · error · FavoriteCategoryNotFoundError

Category not found: ${id}

Error message

Category not found: ${id}

What it means

FavoriteCategoryNotFoundError thrown by updateCategory when no category with the given id exists in storage. The id-based lookup happens inside the storage update callback, so stale ids always fail with this error.

Source

Thrown at packages/core/src/services/favorite/manager.ts:697

      });

      return id;
    } catch (error) {
      if (error instanceof FavoriteError) {
        throw error;
      }
      const errorMessage = error instanceof Error ? error.message : String(error);
      throw new FavoriteStorageError(`Failed to add category: ${errorMessage}`);
    }
  }

  async updateCategory(id: string, updates: Partial<FavoriteCategory>): Promise<void> {
    try {
      await this.storageProvider.updateData(this.STORAGE_KEYS.CATEGORIES, (categories: FavoriteCategory[] | null) => {
        const categoriesList = categories || [];
        const index = categoriesList.findIndex(c => c.id === id);
        if (index === -1) {
          throw new FavoriteCategoryNotFoundError(id);
        }

        categoriesList[index] = {
          ...categoriesList[index],
          ...updates
        };

        return categoriesList;
      });
    } catch (error) {
      if (error instanceof FavoriteError) {
        throw error;
      }
      const errorMessage = error instanceof Error ? error.message : String(error);
      throw new FavoriteStorageError(`Failed to update category: ${errorMessage}`);
    }
  }

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Refresh categories via getCategories() and use a current id
  2. Handle FavoriteCategoryNotFoundError in the UI by re-syncing or dropping the stale reference
  3. Guard multi-tab scenarios by re-validating id right before the update

Example fix

// before
await manager.updateCategory(staleId, { name: 'New' });

// after
const cats = await manager.getCategories();
if (cats.some(c => c.id === staleId)) {
  await manager.updateCategory(staleId, { name: 'New' });
} else {
  // re-sync UI state
}
Defensive patterns

Strategy: validation

Validate before calling

const exists = (await manager.getCategories()).some(c => c.id === id);
if (exists) await manager.updateCategory(id, updates);

Type guard

const isCategoryNotFound = (e: unknown): e is FavoriteCategoryNotFoundError => e instanceof FavoriteCategoryNotFoundError;

Try / catch

try { await manager.updateCategory(id, updates); } catch (e) { if (isCategoryNotFound(e)) { /* refresh UI state */ } throw e; }

Prevention

When it happens

Trigger: Calling updateCategory('cat-123', {...}) after that category was deleted; using an id from a different device/export; race where another tab deleted the category between fetch and update.

Common situations: Stale UI state referencing a deleted category; multi-tab sync where one tab deletes a category another tab is editing; ids from an older import format.

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 linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/d74a045b1174c298. Report an issue: GitHub.