koala73/worldmonitor · error · SafeWebMcpError
switch_monitor input preflight did not run.
Error message
switch_monitor input preflight did not run.
What it means
switch_monitor runs validateSwitchMonitorInput twice: once in a preflight (used for early rejection/analytics) and once in execute. If the execute-time validation returns not-ok, the code assumes an impossible state — the preflight should have caught it — and throws this internal-invariant SafeWebMcpError instead of the proper validation message. Seeing it means the validation pipeline itself is inconsistent, not that your input was merely invalid.
Source
Thrown at src/services/webmcp.ts:1901
description:
'Switch the visible dashboard to World (full), Tech (tech), Finance (finance), Commodity (commodity), Energy (energy), or Good News (happy) through the header variant switcher. Use those stable keys, not display labels. Returns the selected destination and effective dashboard state.',
inputSchema: {
type: 'object',
properties: {
monitor: {
type: 'string',
description: 'Stable monitor key: full, tech, finance, commodity, energy, or happy.',
enum: [...SITE_VARIANTS],
},
},
required: ['monitor'],
additionalProperties: false,
},
annotations: { readOnlyHint: false },
execute: withInvocationLogging(WEBMCP_SPA_TOOL.switchMonitor, async (args, extra) => {
const input = validateSwitchMonitorInput(args);
if (!input.ok) {
throw new SafeWebMcpError('switch_monitor input preflight did not run.');
}
return boundDashboardNavigationResult(await app.switchMonitor(input.monitor, extra));
}, trackEvent, {
preflight: async (args, extra) => {
const input = validateSwitchMonitorInput(args);
if (input.ok) return undefined;
return boundDashboardNavigationResult({
ok: false,
status: 'invalid',
reason: input.reason,
message: input.message,
context: await currentNavigationContext(app, extra),
});
},
}),
},
{
name: WEBMCP_SPA_TOOL.openSettings,View on GitHub (pinned to 9361220cc0)
Solutions
- Retry with a freshly constructed, simple args object like { monitor: '<known-id-from-context>' }.
- Do not mutate the args object after the call; pass a literal.
- Verify the monitor id against get_dashboard_context output before calling.
- If it reproduces with a clean literal, report a bug — this message indicates a broken internal invariant.
Example fix
// before
const args = { monitor: 'ops' };
await tools.call('switch_monitor', args);
args.monitor = 'finance'; // mutation between preflight and execute breaks the invariant
// after
await tools.call('switch_monitor', { monitor: 'finance' }); Defensive patterns
Strategy: validation
Validate before calling
async function canSwitchTo(tools, monitor) {
if (typeof monitor !== 'string' || monitor.length === 0) return false;
const ctx = await tools.call('get_dashboard_context', {});
return Array.isArray(ctx.monitors) && ctx.monitors.some((m) => m.id === monitor);
} Type guard
function isPreflightInvariantError(e) {
return e instanceof Error && e.message === 'switch_monitor input preflight did not run.';
} Try / catch
try {
return await tools.call('switch_monitor', { monitor });
} catch (e) {
if (isPreflightInvariantError(e)) {
// internal invariant broke: retry once with a fresh literal, then report a bug
return tools.call('switch_monitor', { monitor: String(monitor) });
}
throw e;
} Prevention
- Pass a fresh object literal; never mutate args after issuing the call.
- Pre-validate the monitor id with canSwitchTo before calling.
- Avoid proxying/wrapping tool calls in ways that transform args mid-flight.
- Report occurrences — this message indicates a tool-internal bug, not user error.
When it happens
Trigger: A switch_monitor call whose args pass one validation path but fail the other — e.g. args object mutated between preflight and execute, or the preflight/execute validators diverging (a code bug), causing validateSwitchMonitorInput to return ok:false inside execute despite preflight succeeding.
Common situations: Middleware or proxies mutating the args object between preflight and execution; a version mismatch where the host runs a different preflight implementation than the tool; a WorldMonitor regression in validateSwitchMonitorInput.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- validation
- get_intel_timeline requires at least one of domain ("conflic
- INCOMPATIBLE_DELIVERY
- COUNTRIES_LIMIT_EXCEEDED
- TICKERS_LIMIT_EXCEEDED
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/6890d1a158f90f39.
Report an issue: GitHub.