Freika/dawarich · warning

Failed to add photos layer:

Error message

Failed to add photos layer:

What it means

LayerManager.addLayers() adds every layer synchronously except photos, which is awaited inside a try/catch because loading photo images is async and can fail. If _addPhotosLayer throws (broken image URLs, EXIF/decode failures, malformed GeoJSON), the warning is logged and the remaining layers (family, anomalies, points, routes hit, recent point, replay, fog) are still added — only photo markers go missing.

Source

Thrown at app/javascript/controllers/maps/maplibre/layer_manager.js:76

    // Layer order matters - layers added first render below layers added later
    // Order: scratch (bottom) -> heatmap -> areas -> tracks -> routes (visual) -> visits -> places -> photos -> family -> points -> routes-hit (interaction) -> recent-point (top) -> fog (canvas overlay)
    // Note: routes-hit is above points visually but points dragging takes precedence via event ordering

    await this._addScratchLayer(pointsGeoJSON)
    this._addHeatmapLayer(pointsGeoJSON)
    this._addHexagonLayer()
    this._addAreasLayer(areasGeoJSON)
    this._addTracksLayer(tracksGeoJSON)
    this._addRoutesLayer(routesGeoJSON)
    this._addFlightsLayer(flightsGeoJSON)
    this._addVisitsLayer(visitsGeoJSON)
    this._addPlacesLayer(placesGeoJSON)

    // Add photos layer with error handling (async, might fail loading images)
    try {
      await this._addPhotosLayer(photosGeoJSON)
    } catch (error) {
      console.warn("Failed to add photos layer:", error)
    }

    this._addFamilyLayer()
    this._addAnomaliesLayer()
    this._addPointsMvtLayer()
    this._addPointsLayer(pointsGeoJSON)
    this._addRoutesHitLayer() // Add hit target layer after points, will be on top visually
    this._addRecentPointLayer()
    this._addReplayMarkerLayer()
    this._addFogLayer(pointsGeoJSON)

    performanceMonitor.measure("add-layers")
  }

  /**
   * Setup event handlers for layer interactions
   * Only sets up handlers once to prevent duplicates
   */

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Expand the logged error object — it distinguishes URL fetch failures from decode/EXIF failures
  2. Open the photos API endpoint in a browser and confirm every URL in the GeoJSON resolves (watch for 403/404 from storage)
  3. Fix or remove the single bad photo record, then reload — often one broken image aborts the entire batch
  4. If images are external, ensure CORS or proxy headers allow the map origin

Example fix

// before
try {
  await this._addPhotosLayer(photosGeoJSON)
} catch (error) {
  console.warn("Failed to add photos layer:", error)
}
// after
try {
  await this._addPhotosLayer(photosGeoJSON)
} catch (error) {
  console.warn("Failed to add photos layer:", error)
  // Degrade per-photo so one broken image cannot blank the whole layer
  this._addPhotosLayer(photosGeoJSON, { skipFailingImages: true }).catch(() => {})
}
Defensive patterns

Strategy: try-catch

Validate before calling

const validPhotos = {
  type: "FeatureCollection",
  features: (photosGeoJSON?.features || []).filter(
    (f) =>
      f?.geometry &&
      typeof f.properties?.image_url === "string" &&
      f.properties.image_url.length > 0
  ),
}
await this._addPhotosLayer(validPhotos)

Try / catch

try {
  await this._addPhotosLayer(photosGeoJSON)
} catch (error) {
  console.warn("Failed to add photos layer:", error)
  // Photos are non-critical: continue adding the remaining layers
}

Prevention

When it happens

Trigger: photosGeoJSON containing features with broken or expired image URLs; a photo whose EXIF parsing or image decode fails inside the photos layer; malformed photos GeoJSON (missing geometry or properties); object storage/CDN unreachable so image prefetch rejects.

Common situations: Self-hosted Dawarich with S3/MinIO storage misconfigured (wrong or unsigned URLs); photos synced from Immich or GPX imports with stale URLs; reverse proxy blocking image content types; a single corrupt photo aborting the whole batch.

Related errors


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