{"record":{"id":"8b8172bc2ffcec3c","repo":"koala73/worldmonitor","slug":"map-unavailable","errorCode":"map_unavailable","errorMessage":"Map is not available.","messagePattern":"Map is not available\\.","errorType":"exception","errorClass":"DashboardBindingError","httpStatus":null,"severity":"error","filePath":"src/app/webmcp-dashboard.ts","lineNumber":43,"sourceCode":"    reason,\n    message: reason === 'viewport_superseded'\n      ? 'Map movement was superseded by a newer viewport action.'\n      : reason === 'renderer_changed'\n        ? 'Map renderer changed before the movement completed.'\n        : 'Map movement was interrupted before it completed.',\n    targets: result.targets.map((target) => ({ ...target, status: 'denied', reason })),\n  };\n}\n\nexport function getWebMcpDashboardContext(\n  ctx: AppContext,\n  variant: string,\n): DashboardContextSnapshot {\n  if (ctx.isDestroyed) {\n    throw new DashboardBindingError('app_destroyed', 'Dashboard is no longer available.');\n  }\n  if (!ctx.map) {\n    throw new DashboardBindingError('map_unavailable', 'Map is not available.');\n  }\n\n  const mapState = ctx.map.getState();\n  const center = ctx.map.getCenter();\n\n  return {\n    variant,\n    map: {\n      view: mapState.view,\n      center,\n      zoom: mapState.zoom,\n      timeRange: mapState.timeRange,\n      enabledLayers: Object.entries(mapState.layers)\n        .filter(([, enabled]) => enabled === true)\n        .map(([layer]) => layer),\n    },\n    panels: {\n      mounted: Object.keys(ctx.panels),","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/koala73/worldmonitor/blob/eeab0a219fce0f02a00603b532dbae9041b934ac/src/app/webmcp-dashboard.ts#L25-L61","documentation":"DashboardBindingError 'map_unavailable' thrown by getWebMcpDashboardContext() when ctx.map is falsy on a live (not destroyed) app. The context snapshot includes map view/center/zoom/timeRange, so it refuses rather than fabricate a map-less snapshot. Distinct from 'app_destroyed' (previous guard, line 40): the app is fine, the map renderer specifically never came up.","triggerScenarios":"Calling get_dashboard_context before the map renderer initialized (it is created lazily), when WebGL is unavailable in the browser so map creation failed, when the map is disabled in settings or not part of the current variant, or on a headless/CI browser without GPU.","commonSituations":"Agent tool calls arriving during early startup before the map chunk finishes loading; browsers with WebGL blocked (hardware acceleration off, remote desktop, locked-down enterprise chrome); e2e test environments where the map panel is disabled to keep tests light.","solutions":["Wait for map initialization (or check ctx.map truthy) before requesting dashboard context","If the map legitimately fails to init, check the browser console for WebGL/renderer errors and either fix the environment or treat 'map_unavailable' as a degraded-but-valid mode that omits map fields","Guard tool registration: only advertise map-dependent tools when ctx.map exists"],"exampleFix":"// before\nconst snapshot = getWebMcpDashboardContext(ctx, variant); // throws 'Map is not available.'\n\n// after\nif (!ctx.map) {\n  return { ok: false, status: 'denied', reason: 'map_unavailable' } as const;\n}\nconst snapshot = getWebMcpDashboardContext(ctx, variant);","handlingStrategy":"type-guard","validationCode":"if (!ctx.map) {\n  return { ok: false, status: 'denied', reason: 'map_unavailable' }; // degrade gracefully instead of throwing\n}","typeGuard":"function hasMapRenderer(ctx: AppContext): ctx is AppContext & { map: NonNullable<AppContext['map']> } {\n  return !ctx.isDestroyed && ctx.map != null;\n}","tryCatchPattern":"try { snapshot = getWebMcpDashboardContext(ctx, variant); } catch (e) { if (e instanceof DashboardBindingError && e.code === 'map_unavailable') snapshot = snapshotWithoutMap(variant); else throw e; }","preventionTips":["Await map initialization before exposing map-dependent tools","Detect WebGL up front and disable those tools when unsupported","Offer a map-less degraded snapshot instead of failing the whole context call"],"tags":["webmcp","agent-tools","map-renderer","webgl"],"backgroundTag":"optional-feature-unavailable","analyzedSha":"eeab0a219fce0f02a00603b532dbae9041b934ac","analyzedAt":"2026-08-21T16:51:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}