Freika/dawarich · info

[MapInitializer] No features to fit bounds to

Error message

[MapInitializer] No features to fit bounds to

What it means

A guard, not a failure: MapInitializer.fitToBounds refuses to build an LngLatBounds and call map.fitBounds when the supplied FeatureCollection has zero features, because fitting bounds to nothing is undefined (MapLibre would throw or zoom the world). The warning marks the skip so developers understand why the map kept its previous view.

Source

Thrown at app/javascript/controllers/maps/maplibre/map_initializer.js:141

    map.addControl(
      new maplibregl.AttributionControl({ compact: true }),
      "bottom-right",
    )

    return map
  }

  /**
   * Fit map to bounds of GeoJSON features
   * @param {maplibregl.Map} map - The map instance
   * @param {Object} geojson - GeoJSON FeatureCollection
   * @param {Object} options - Fit bounds options
   */
  static fitToBounds(map, geojson, options = {}) {
    const { padding = 50, maxZoom = 15 } = options

    if (!geojson?.features?.length) {
      console.warn("[MapInitializer] No features to fit bounds to")
      return
    }

    const coordinates = geojson.features.map((f) => f.geometry.coordinates)

    const bounds = coordinates.reduce((bounds, coord) => {
      return bounds.extend(coord)
    }, new maplibregl.LngLatBounds(coordinates[0], coordinates[0]))

    map.fitBounds(bounds, {
      padding,
      maxZoom,
    })
  }
}

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Confirm the empty set is expected (new account or heavy filters) — nothing is broken
  2. When empty, provide a sensible default view instead of keeping a stale one
  3. If data should exist, check the upstream fetch — an auth failure can degrade to an empty collection
  4. Downgrade to console.debug in production to reduce noise

Example fix

// before
if (!geojson?.features?.length) {
  console.warn("[MapInitializer] No features to fit bounds to")
  return
}
// after
if (!geojson?.features?.length) {
  console.debug("[MapInitializer] No features to fit bounds to")
  map.jumpTo({ center: [0, 0], zoom: 2 }) // deterministic default view
  return
}
Defensive patterns

Strategy: validation

Validate before calling

const hasFeatures =
  Array.isArray(geojson?.features) &&
  geojson.features.length > 0 &&
  geojson.features.some((f) => f?.geometry?.coordinates)
if (!hasFeatures) {
  map.jumpTo({ center: DEFAULT_CENTER, zoom: DEFAULT_ZOOM })
  return
}

Type guard

/** @param {unknown} gj @returns {boolean} */
function isNonEmptyFeatureCollection(gj) {
  return Boolean(
    gj &&
    typeof gj === "object" &&
    Array.isArray(gj.features) &&
    gj.features.length > 0
  )
}

Prevention

When it happens

Trigger: A brand-new account with no points yet; date-range, viewport, or layer filters excluding every feature; the API returning an empty FeatureCollection before the first import completes; fitToBounds called during teardown with already-cleared data.

Common situations: Fresh self-hosted installs before the first Owntracks/Overland import; filters narrower than the tracked data; demo instances with empty seeds; an upstream auth failure silently degrading to an empty collection.

Related errors


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