{"record":{"id":"9e523975d6ba8e62","repo":"Freika/dawarich","slug":"realtime-controller-points-layer-not-found","errorCode":null,"errorMessage":"[Realtime Controller] Points layer not found","messagePattern":"\\[Realtime Controller\\] Points layer not found","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"app/javascript/controllers/maps/maplibre_realtime_controller.js","lineNumber":182,"sourceCode":"  }\n\n  /**\n   * Handle new point\n   * Point data is broadcast as: [lat, lon, battery, altitude, timestamp, velocity, id, country_name]\n   */\n  handleNewPoint(pointData) {\n    const mapsController = this.mapsV2Controller\n    if (!mapsController) {\n      console.warn(\"[Realtime Controller] Maps controller not found\")\n      return\n    }\n\n    const [lat, lon, battery, altitude, timestamp, velocity, id, countryName] =\n      pointData\n\n    const pointsLayer = mapsController.layerManager?.getLayer(\"points\")\n    if (!pointsLayer) {\n      console.warn(\"[Realtime Controller] Points layer not found\")\n      return\n    }\n\n    const currentData = pointsLayer.data || {\n      type: \"FeatureCollection\",\n      features: [],\n    }\n    const features = [...(currentData.features || [])]\n\n    features.push({\n      type: \"Feature\",\n      geometry: {\n        type: \"Point\",\n        coordinates: [parseFloat(lon), parseFloat(lat)],\n      },\n      properties: {\n        id: parseInt(id, 10),\n        latitude: parseFloat(lat),","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/Freika/dawarich/blob/97fad417c5a11b0eb11157890635e015723a2e97/app/javascript/controllers/maps/maplibre_realtime_controller.js#L164-L200","documentation":"After resolving the Maps V2 controller, handleNewPoint looks up the points layer via mapsController.layerManager?.getLayer(\"points\") and warns when it is not registered. The points layer only exists after the map controller has initialized its LayerManager and added the layer, so this means a realtime point arrived before the layer registry was populated (or the layer was removed). The incoming point is dropped.","triggerScenarios":"An ActionCable new_point broadcast lands during page load before maplibre_controller.connect() has created and registered the points layer; or the points layer was hidden/removed (layer settings) while live mode is still subscribed; or the layer was registered under a different id than \"points\".","commonSituations":"Slow map init on mobile combined with immediate GPS uploads from a phone; Turbo navigation away from the map while the cable subscription briefly persists; toggling point-layer visibility off in settings then receiving live updates; refactoring layer ids in LayerManager.","solutions":["Delay channel subscription until the map reports ready (subscribe from a map:ready callback/event instead of realtime controller connect()).","Buffer incoming point features in the realtime controller while the layer is absent and flush them once getLayer(\"points\") resolves.","Verify the layer id registered in LayerManager for points is exactly \"points\" after any layer refactor."],"exampleFix":"// before\nconst pointsLayer = mapsController.layerManager?.getLayer(\"points\")\nif (!pointsLayer) {\n  console.warn(\"[Realtime Controller] Points layer not found\")\n  return\n}\n\n// after\nconst pointsLayer = mapsController.layerManager?.getLayer(\"points\")\nif (!pointsLayer) {\n  this.pendingPoints = this.pendingPoints || []\n  this.pendingPoints.push(pointData)\n  return\n}","handlingStrategy":"validation","validationCode":"const layer = mapsController.layerManager?.getLayer(\"points\")\nif (!layer) { this.pendingPoints.push(pointData); return }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check getLayer(id) before every realtime mutation of a layer.","Buffer broadcasts that arrive before map init and flush on map ready.","Keep layer id strings (\"points\", \"recentPoint\") as exported constants shared by producers and consumers."],"tags":["stimulus","maplibre","actioncable","layer-not-found","realtime"],"backgroundTag":"map-layer-not-initialized","analyzedSha":"97fad417c5a11b0eb11157890635e015723a2e97","analyzedAt":"2026-08-21T17:04:17.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}