{"record":{"id":"be3ec1ba3523f81d","repo":"koala73/worldmonitor","slug":"dashboard-tab-result-exceeded-the-safe-output-limi","errorCode":null,"errorMessage":"Dashboard tab result exceeded the safe output limit.","messagePattern":"Dashboard tab result exceeded the safe output limit\\.","errorType":"error_code","errorClass":"SafeWebMcpError","httpStatus":null,"severity":"error","filePath":"src/services/webmcp.ts","lineNumber":1552,"sourceCode":"  const bounded: DashboardTabMutationResult = {\n    ok: result.ok === true,\n    status: result.status,\n    actionType: result.actionType,\n    message: boundedText(result.message, 240),\n    ...(result.reason ? { reason: boundedText(result.reason, 64) as DashboardTabMutationResult['reason'] } : {}),\n    ...(result.tabId ? { tabId: boundedText(result.tabId, 64) } : {}),\n    ...(result.name ? { name: boundedText(result.name, DASHBOARD_TAB_NAME_MAX_LENGTH) } : {}),\n    ...(result.activeTabId ? { activeTabId: boundedText(result.activeTabId, 64) } : {}),\n    ...(result.unchanged === true ? { unchanged: true } : {}),\n    ...(result.alreadyExisted === true ? { alreadyExisted: true } : {}),\n    ...(typeof result.persisted === 'boolean' ? { persisted: result.persisted } : {}),\n    ...(typeof result.tabCount === 'number' ? { tabCount: Math.max(0, Math.floor(result.tabCount)) } : {}),\n    ...(typeof result.canCreate === 'boolean' ? { canCreate: result.canCreate } : {}),\n    ...(result.cap === null || typeof result.cap === 'number' ? { cap: result.cap } : {}),\n    ...(result.lockReason ? { lockReason: boundedText(result.lockReason, 32) as DashboardTabMutationResult['lockReason'] } : {}),\n  };\n  if (JSON.stringify(bounded).length > MAX_OUTPUT_CHARS) {\n    throw new SafeWebMcpError('Dashboard tab result exceeded the safe output limit.');\n  }\n  return bounded;\n}\n\nconst EMPTY_NAV_CONTEXT: DashboardContextSnapshot = {\n  variant: '',\n  map: {\n    view: '',\n    center: null,\n    zoom: 0,\n    timeRange: '',\n    enabledLayers: [],\n  },\n  panels: {\n    mounted: [],\n    enabled: [],\n  },\n};","sourceCodeStart":1534,"sourceCodeEnd":1570,"githubUrl":"https://github.com/koala73/worldmonitor/blob/9361220cc013571781071f0206e4d80fd14b2f7f/src/services/webmcp.ts#L1534-L1570","documentation":"boundDashboardTabMutation sanitizes a tab mutation result (create/rename/delete/select), coercing counts, capping lockReason to 32 chars, and then asserts the serialized result fits MAX_OUTPUT_CHARS. If it still exceeds the budget it throws this SafeWebMcpError. Mutation results are tiny by design, so hitting this indicates the result structurally ballooned beyond what the bounder can trim.","triggerScenarios":"A create_dashboard_tab / rename_dashboard_tab / delete_dashboard_tab / select_dashboard_tab call whose bounded result object still serializes above MAX_OUTPUT_CHARS — practically only when the result carries oversized fields the bounder does not truncate.","commonSituations":"A dashboard version returning extra unbounded fields in the mutation result; extremely long tab ids or lockReason variants; a regression where the bounder's field whitelist stopped covering a new large field.","solutions":["Retry the mutation once; this is not expected in normal operation and may be transient state.","Check whether you are on a dashboard version that added fields to DashboardTabMutationResult; upgrade or downgrade to a matched pair of tool/app versions.","Shorten the tab name/id you are mutating to rule out oversize user input.","Report a bug with the tool name and args — the bounder should always produce a sub-budget mutation result."],"exampleFix":"// before\nawait tools.call('rename_dashboard_tab', { id, name: 'x'.repeat(5000) });\n// after\nawait tools.call('rename_dashboard_tab', { id, name: name.slice(0, 64) });","handlingStrategy":"try-catch","validationCode":"function validTabMutationArgs(args) {\n  return typeof args.id === 'string' && args.id.length <= 128\n    && (args.name === undefined || (typeof args.name === 'string' && args.name.length <= 64));\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await tools.call('rename_dashboard_tab', { id, name });\n} catch (e) {\n  if (e.message.includes('tab result exceeded')) {\n    // unexpected: mutation results are tiny; log and retry once, then report\n    console.error('oversized tab mutation result', { id, name: name.length });\n    return tools.call('rename_dashboard_tab', { id, name: name.slice(0, 32) });\n  }\n  throw e;\n}","preventionTips":["Bound user-supplied tab names to a sane length (<= 64 chars) before calling.","Keep tab ids short and generated, not free-form user text.","Keep tool and dashboard versions matched.","Treat occurrences as a bug-report condition with args captured."],"tags":["webmcp","output-budget","tabs","mutation"],"backgroundTag":"response-size-limit-exceeded","analyzedSha":"9361220cc013571781071f0206e4d80fd14b2f7f","analyzedAt":"2026-09-01T10:32:37.851Z","contentChangedAt":"2026-09-01T10:32:37.851Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}