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

  1. Retry the navigation — if a transient field inflated the envelope it may pass on a second call.
  2. Update WorldMonitor so tool bounder and dashboard payload shapes are from the same version.
  3. Reduce navigation input surface (e.g. target a monitor/country without huge metadata) to confirm the trigger.
  4. 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

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


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