koala73/worldmonitor · error · DashboardPanelCatalogError

invalid_category

invalid_category

Error message

category must be a known panel category key.

What it means

listDashboardPanelCatalog() validates query.category against a camelCase-style regex and the set of known panel category keys (PANEL_CATEGORY_MAP keys plus 'other'). An unknown or malformed category string throws DashboardPanelCatalogError with reason 'invalid_category'. The catalog only supports filtering by categories that actually exist in the panel registry.

Source

Thrown at src/services/webmcp-panel-catalog.ts:165

  const variantFilter = query.variant;
  if (variantFilter !== undefined) {
    if (typeof variantFilter !== 'string' || !isSiteVariant(variantFilter)) {
      throw new DashboardPanelCatalogError(
        'invalid_variant',
        'variant must be one of: full, tech, finance, commodity, energy, happy.',
      );
    }
  }

  const categoryFilter = query.category;
  if (categoryFilter !== undefined) {
    if (
      typeof categoryFilter !== 'string'
      || !CATEGORY_KEY_RE.test(categoryFilter)
      || !PANEL_CATEGORY_KEY_SET.has(categoryFilter)
    ) {
      throw new DashboardPanelCatalogError(
        'invalid_category',
        'category must be a known panel category key.',
      );
    }
  }

  if (query.enabled !== undefined && typeof query.enabled !== 'boolean') {
    throw new DashboardPanelCatalogError(
      'malformed_arguments',
      'enabled must be a boolean.',
    );
  }
  if (query.available !== undefined && typeof query.available !== 'boolean') {
    throw new DashboardPanelCatalogError(
      'malformed_arguments',
      'available must be a boolean.',
    );
  }

View on GitHub (pinned to 9361220cc0)

Solutions

  1. Use a category key from DASHBOARD_PANEL_CATALOG_CATEGORY_KEYS (exported from webmcp-panel-catalog.ts) instead of a free-form string.
  2. Validate: typeof category === 'string' && /^[a-z][a-zA-Z0-9]*$/.test(category) && DASHBOARD_PANEL_CATALOG_CATEGORY_KEYS.includes(category) before calling.
  3. Catch DashboardPanelCatalogError with reason 'invalid_category' and fall back to listing without a category filter.
  4. After adding/renaming categories in PANEL_CATEGORY_MAP, update all callers that reference the old key.

Example fix

// before
listDashboardPanelCatalog(live, { category: 'markets' });
// after
const category = DASHBOARD_PANEL_CATALOG_CATEGORY_KEYS.includes(requested) ? requested : undefined;
listDashboardPanelCatalog(live, category ? { category } : {});
Defensive patterns

Strategy: validation

Validate before calling

import { DASHBOARD_PANEL_CATALOG_CATEGORY_KEYS } from '@/services/webmcp-panel-catalog';
const category = DASHBOARD_PANEL_CATALOG_CATEGORY_KEYS.includes(rawCategory as never)
  ? rawCategory
  : undefined;

Type guard

function isPanelCategoryKey(value: unknown): value is string {
  return typeof value === 'string'
    && /^[a-z][a-zA-Z0-9]*$/.test(value)
    && DASHBOARD_PANEL_CATALOG_CATEGORY_KEYS.includes(value);
}

Try / catch

try {
  return listDashboardPanelCatalog(live, query);
} catch (err) {
  if (err instanceof DashboardPanelCatalogError && err.reason === 'invalid_category') {
    const { category, ...rest } = query;
    return listDashboardPanelCatalog(live, rest);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling listDashboardPanelCatalog(live, { category: 'markets' }) where 'markets' is not a key of PANEL_CATEGORY_MAP; categories with uppercase initials, hyphens, or spaces failing CATEGORY_KEY_RE (e.g. 'Market-Data', 'AI tools'); a category key removed/renamed in config/panels.

Common situations: Hardcoding a category name from memory instead of importing DASHBOARD_PANEL_CATALOG_CATEGORY_KEYS; an agent guessing a plausible category; categories drifting after PANEL_CATEGORY_MAP was reorganized.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01). Data as JSON: /api/errors/2ef72202da49be9d. Report an issue: GitHub.