koala73/worldmonitor · error · DashboardPanelCatalogError
invalid_variant
invalid_variant
Error message
variant must be one of: full, tech, finance, commodity, energy, happy.
What it means
listDashboardPanelCatalog() validates live.currentVariant with isSiteVariant() before enumerating panels. An unrecognized current variant makes variant-aware panel lookups (VARIANT_DEFAULTS, availability sets) impossible, so it throws DashboardPanelCatalogError with reason 'invalid_variant'. Acceptable values are full, tech, finance, commodity, energy, happy.
Source
Thrown at src/services/webmcp-panel-catalog.ts:142
export function getDashboardPanelCategoryKey(panelId: string, variant: string): string {
for (const [key, definition] of Object.entries(PANEL_CATEGORY_MAP)) {
if (definition.variants && !definition.variants.includes(variant)) continue;
if (definition.panelKeys.includes(panelId)) return key;
}
for (const [key, definition] of Object.entries(PANEL_CATEGORY_MAP)) {
if (definition.panelKeys.includes(panelId)) return key;
}
return 'other';
}
export function listDashboardPanelCatalog(
live: DashboardPanelCatalogLiveState,
query: DashboardPanelCatalogQuery = {},
): DashboardPanelCatalogPage {
const currentVariant = live.currentVariant;
if (!isSiteVariant(currentVariant)) {
throw new DashboardPanelCatalogError(
'invalid_variant',
'variant must be one of: full, tech, finance, commodity, energy, happy.',
);
}
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 (View on GitHub (pinned to 9361220cc0)
Solutions
- Ensure live.currentVariant is one of 'full','tech','finance','commodity','energy','happy'; consult @/config/variant for the source of truth.
- Normalize and validate with isSiteVariant() when constructing the live state; fall back to the default variant if invalid.
- Map legacy/alias variant names to current ids before the call.
- Catch DashboardPanelCatalogError with reason 'invalid_variant' to report the accepted variants back to the caller.
Example fix
// before
listDashboardPanelCatalog({ currentVariant: appConfig.variant, ... });
// after
const variant = isSiteVariant(appConfig.variant) ? appConfig.variant : VARIANT_DEFAULTS.defaultVariant;
listDashboardPanelCatalog({ currentVariant: variant, ... }); Defensive patterns
Strategy: validation
Validate before calling
import { isSiteVariant } from '@/config/variant';
if (!isSiteVariant(live.currentVariant)) {
throw new Error(`currentVariant must be one of full|tech|finance|commodity|energy|happy, got '${live.currentVariant}'`);
} Type guard
function hasValidCurrentVariant(live: DashboardPanelCatalogLiveState): live is DashboardPanelCatalogLiveState & { currentVariant: SiteVariant } {
return isSiteVariant(live.currentVariant);
} Try / catch
try {
return listDashboardPanelCatalog(live, query);
} catch (err) {
if (err instanceof DashboardPanelCatalogError && err.reason === 'invalid_variant') {
return listDashboardPanelCatalog({ ...live, currentVariant: DEFAULT_VARIANT }, query);
}
throw err;
} Prevention
- Resolve currentVariant through isSiteVariant() at dashboard bootstrap, before any catalog call.
- Keep hostname/config→variant mappings in sync with SITE_VARIANTS.
- Fall back to a known-good default variant when the resolved value is unrecognized.
- Write a unit test per variant to catch registry drift early.
When it happens
Trigger: Supplying a DashboardPanelCatalogLiveState whose currentVariant is not exactly one of the six SITE_VARIANTS — e.g. 'main', 'default', 'FULL', an empty string, or a stale value persisted before a variant rename — when listDashboardPanelCatalog runs (via listWebMcpDashboardPanels).
Common situations: currentVariant sourced from config, localStorage, or a hostname→variant mapping that drifted from SITE_VARIANTS; bootstrapping the dashboard before the variant is resolved; case mismatch after lowercasing was removed.
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/ea639e42dfda493d.
Report an issue: GitHub.