Freika/dawarich · warning

[Maps V2] Visits layer not found, cannot update

Error message

[Maps V2] Visits layer not found, cannot update

What it means

When a visit creation event arrives, VisitsManager upserts the saved visit into the 'visits' layer (or fetches the viewport set on first load) and auto-enables the layer so the new visit is immediately visible. If LayerManager has no 'visits' layer registered, it warns and returns, so the just-created visit will not appear on the map until reload.

Source

Thrown at app/javascript/controllers/maps/maplibre/visits_manager.js:409

    if (controller) {
      controller.open(lat, lng, this.controller)
    } else {
      Toast.error(translate("messages.visit_creation_controller_not_available"))
    }
  }

  /**
   * Handle visit creation event - reload visits, update layer, and
   * enable the Visits layer so the new visit is immediately visible.
   * Without auto-enabling, users would create a visit and see nothing
   * on the map because the layer toggle was off.
   */
  async handleVisitCreated(event) {
    try {
      const visitsLayer = this.layerManager.getLayer("visits")
      if (!visitsLayer) {
        console.warn("[Maps V2] Visits layer not found, cannot update")
        return
      }

      const visit = event?.detail?.visit
      let visits
      if (visit && this.filterManager.allVisits?.length) {
        // Layer already populated — append/replace this visit locally instead
        // of re-pulling the whole viewport from the backend.
        visits = this._upsertVisit(this.filterManager.allVisits, visit)
      } else {
        // Initial load: fetch the viewport set once, then make sure the
        // just-saved visit is included even if it falls outside the current
        // date range or viewport bounds (otherwise its marker never appears).
        const fetched = await this.fetchVisitsForCurrentViewport()
        visits = visit ? this._upsertVisit(fetched, visit) : fetched
      }

      this.filterManager.setAllVisits(visits)

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Confirm timing: if the event fires during map init, queue it and replay once addLayers completes
  2. Unsubscribe document-level listeners in the manager's disconnect/destroy lifecycle
  3. Verify the layer id string matches what LayerManager registers ('visits')
  4. If the visits layer is intentionally off, downgrade to debug logging

Example fix

// before
const visitsLayer = this.layerManager.getLayer("visits")
if (!visitsLayer) {
  console.warn("[Maps V2] Visits layer not found, cannot update")
  return
}
// after
const visitsLayer = this.layerManager.getLayer("visits")
if (!visitsLayer) {
  if (this.layersReady) console.warn("[Maps V2] Visits layer not found, cannot update")
  else this.pendingVisitEvents.push(event) // replay after layers initialize
  return
}
Defensive patterns

Strategy: type-guard

Validate before calling

const visitsLayer = this.layerManager?.getLayer("visits")
if (!visitsLayer || typeof visitsLayer.setData !== "function") {
  if (this.layersReady) console.warn("[Maps V2] Visits layer not found, cannot update")
  else this.pendingVisitEvents.push(event) // replay after addLayers
  return
}

Type guard

/** @param {unknown} layer @returns {boolean} */
function isVisitsLayer(layer) {
  return Boolean(
    layer &&
    typeof layer === "object" &&
    typeof layer.setData === "function"
  )
}

Try / catch

try {
  await this._reloadVisits(visitsLayer)
} catch (error) {
  console.warn("[Maps V2] Visits reload failed:", error)
}

Prevention

When it happens

Trigger: A visit saved before the map finished adding layers; the document-level event reaching a page whose map was torn down by Turbo navigation while the listener survived; the visits layer disabled or renamed; the event broadcast from another browser tab whose map lacks the layer.

Common situations: Multi-tab workflows; Turbo cache restores where managers outlive their layers; races between initial layer setup and a quick visit save; layer id changes during refactors.

Related errors


AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21). Data as JSON: /api/errors/f8029060bdabc990. Report an issue: GitHub.