koala73/worldmonitor · error · MissionPresetCatalogError
malformed_arguments
malformed_arguments
Error message
Unknown mission preset: ${presetId} What it means
buildMissionPresetCatalogItem() resolves a mission preset id through getMissionPreset() before building its catalog row. If the id does not match any registered preset in the MISSION_PRESETS registry, the function throws MissionPresetCatalogError with reason 'malformed_arguments'. It guards the catalog against silently emitting rows for non-existent presets.
Source
Thrown at src/services/webmcp-mission-preset-catalog.ts:166
function unavailableReason(item: {
monitorCompatible: boolean;
entitled: boolean;
targetCancellationSupported?: boolean;
}): MissionPresetUnavailableReason | undefined {
if (!item.monitorCompatible) return 'preset_incompatible';
if (!item.entitled) return 'preset_not_entitled';
if (item.targetCancellationSupported === false) return 'target_cancellation_unsupported';
return undefined;
}
export function buildMissionPresetCatalogItem(
presetId: MissionPresetId,
live: MissionPresetCatalogLiveState,
): MissionPresetCatalogItem {
const preset = getMissionPreset(presetId);
if (!preset) {
throw new MissionPresetCatalogError('malformed_arguments', `Unknown mission preset: ${presetId}`);
}
const matchingPanels = getMissionPresetPanelMatches(presetId, live.variant);
const monitorCompatible = isMissionPresetMonitorCompatible(presetId, live.variant);
const panelIds = monitorCompatible
? preset.panels.filter((panelId) => panelId === 'map' || matchingPanels.includes(panelId))
: [];
const entitled = resolveEntitled(matchingPanels, live);
const reason = unavailableReason({
monitorCompatible,
entitled,
targetCancellationSupported: live.targetCancellationSupported,
});
const available = reason === undefined;
return {
id: preset.id,
label: preset.label,View on GitHub (pinned to 9361220cc0)
Solutions
- Validate the presetId against the known preset registry (getMissionPreset(presetId) !== undefined or a MissionPresetId union check) before calling buildMissionPresetCatalogItem.
- Import preset ids from the typed MissionPresetId union / MISSION_PRESETS keys instead of hardcoding strings.
- Catch MissionPresetCatalogError and check reason === 'malformed_arguments' to return a friendly 'unknown preset' message listing valid ids.
- If the id came from persisted state, migrate or clear stale preset ids after preset renames.
Example fix
// before
buildMissionPresetCatalogItem(params.presetId as MissionPresetId, live);
// after
if (getMissionPreset(params.presetId) === undefined) {
throw new Error(`presetId '${params.presetId}' is not a known mission preset`);
}
const item = buildMissionPresetCatalogItem(params.presetId, live); Defensive patterns
Strategy: type-guard
Validate before calling
import { MISSION_PRESETS } from '@/services/mission-presets';
const KNOWN_PRESET_IDS = new Set(Object.keys(MISSION_PRESETS));
if (!KNOWN_PRESET_IDS.has(presetId)) {
throw new Error(`Unknown mission preset '${presetId}'. Valid: ${[...KNOWN_PRESET_IDS].join(', ')}`);
} Type guard
function isMissionPresetId(value: string): value is MissionPresetId {
return Object.prototype.hasOwnProperty.call(MISSION_PRESETS, value);
} Try / catch
try {
const item = buildMissionPresetCatalogItem(presetId, live);
} catch (err) {
if (err instanceof MissionPresetCatalogError && err.reason === 'malformed_arguments') {
return { ok: false, error: `Unknown preset '${presetId}'` };
}
throw err;
} Prevention
- Only pass ids typed as MissionPresetId; never cast raw strings.
- Validate externally supplied (MCP/LLM) preset ids against the registry before use.
- Migrate persisted preset ids when the MISSION_PRESETS registry changes.
- List valid ids in error messages surfaced to agents so they can self-correct.
When it happens
Trigger: Calling buildMissionPresetCatalogItem('nonexistent', live) (or via presets/item accessors) with a presetId string that is not a key of the MISSION_PRESETS registry — e.g. a typo, a preset removed in a refactor, or an id passed through from an external MCP tool call.
Common situations: Storing preset ids in settings/URL and replaying them after the preset was renamed or deleted; accepting an LLM/agent-supplied preset id from the webmcp mission-preset list tool without validating it; hand-typing a preset id instead of importing a typed MissionPresetId constant.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- invalid_variant
- Unknown mission preset: ${presetId}
- Mission preset ${presetId} is not available on this variant
- invalid_category
- validation
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/aa2ed1b8277b7675.
Report an issue: GitHub.