koala73/worldmonitor · error · SafeWebMcpError
Dashboard navigation result exceeded the safe output limit.
Error message
Dashboard navigation result exceeded the safe output limit.
What it means
boundDashboardNavigationResult composes a navigation envelope plus a context snapshot whose size is pre-budgeted (contextBudget = NAVIGATION_MAX_OUTPUT_CHARS - envelopeChars + 2), then does a final check against NAVIGATION_MAX_OUTPUT_CHARS. If the final serialized navigation result (e.g. from switch_monitor or focus_country) still exceeds the navigation output budget it throws this SafeWebMcpError. It is the last-resort guard for navigation payloads.
Source
Thrown at src/services/webmcp.ts:1603
ok: result.ok === true,
status: result.status,
...(result.destination ? { destination: boundedText(result.destination, 32) } : {}),
...(result.navigation ? { navigation: boundedText(result.navigation, 16) } : {}),
...(result.overlay ? { overlay: boundedText(result.overlay, 16) } : {}),
...(result.tab ? { tab: boundedText(result.tab, 32) } : {}),
...(result.reason ? { reason: boundedText(result.reason, 64) } : {}),
message: boundedText(result.message, 240),
context: {},
};
const envelopeChars = JSON.stringify(envelope).length;
// `"context":{}` is already in the envelope; the empty object is 2 chars.
const contextBudget = Math.max(0, NAVIGATION_MAX_OUTPUT_CHARS - envelopeChars + 2);
const bounded = {
...envelope,
context: boundDashboardContext(result.context ?? EMPTY_NAV_CONTEXT, contextBudget),
};
if (JSON.stringify(bounded).length > NAVIGATION_MAX_OUTPUT_CHARS) {
throw new SafeWebMcpError('Dashboard navigation result exceeded the safe output limit.');
}
return bounded;
}
async function applyDashboardTabAction(
action: DashboardTabAction,
app: WebMcpAppBindings,
options?: WebMcpExecutionOptions,
): Promise<DashboardTabActionResult> {
const result = await app.applyDashboardTabAction(action, options);
return isDashboardTabListSnapshot(result)
? boundDashboardTabList(result, action.type === 'list' ? action.cursor : undefined)
: boundDashboardTabMutation(result);
}
function hasOnlyOwnKeys(
value: Record<string, unknown>,
allowedKeys: readonly string[],View on GitHub (pinned to 9361220cc0)
Solutions
- Retry the navigation — if a transient field inflated the envelope it may pass on a second call.
- Update WorldMonitor so tool bounder and dashboard payload shapes are from the same version.
- Reduce navigation input surface (e.g. target a monitor/country without huge metadata) to confirm the trigger.
- Report a bug with the tool name — the envelope should be structurally bounded, not able to exceed the budget.
Example fix
// before
await tools.call('switch_monitor', { monitor: someUnvalidatedInput });
// after
const monitors = await tools.call('get_dashboard_context', {});
const valid = monitors.monitors.some((m) => m.id === target);
if (valid) await tools.call('switch_monitor', { monitor: target }); Defensive patterns
Strategy: try-catch
Validate before calling
async function monitorExists(tools, monitor) {
const ctx = await tools.call('get_dashboard_context', {});
return Array.isArray(ctx.monitors) && ctx.monitors.some((m) => m.id === monitor);
} Try / catch
try {
return await tools.call('switch_monitor', { monitor });
} catch (e) {
if (e.message.includes('navigation result exceeded')) {
console.error('oversized navigation result for', monitor);
// fall back to a context refresh instead of the full navigation payload
return tools.call('get_dashboard_context', {});
}
throw e;
} Prevention
- Validate target monitor/country ids against get_dashboard_context before navigating.
- Keep tool and app versions aligned so envelope shapes stay bounded.
- Avoid navigating to targets known to carry huge metadata until trimmed.
- Treat repeated occurrences as a regression to report upstream.
When it happens
Trigger: A navigation tool call (switch_monitor, focus_country, applyDashboardAction-backed tools) where the envelope itself is so large that even after shrinking the context to zero the total exceeds NAVIGATION_MAX_OUTPUT_CHARS.
Common situations: A dashboard version adding large fields to the navigation envelope; monitors/countries with pathological metadata inflating envelope fields; version mismatch between tool bounder and app payload shape.
Related errors
- Dashboard panel catalog exceeded the safe output limit.
- Dashboard tab list exceeded the safe output limit.
- Dashboard tab result exceeded the safe output limit.
- Country brief panel is not initialised
- app_destroyed
AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-09-01).
Data as JSON: /api/errors/b01dd361c162354e.
Report an issue: GitHub.