Freika/dawarich · warning

Failed to load scratch layer:

Error message

Failed to load scratch layer:

What it means

The scratch layer (freehand drawing on the map) is code-split and loaded on demand through lazyLoader.loadLayer('scratch') when settings.scratchEnabled is on. This warning means the dynamic import or the layer's constructor/add() threw: most often a chunk load error after a new deploy invalidated old asset hashes, otherwise a runtime bug in the ScratchLayer module itself.

Source

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

    )
  }

  // Private methods for individual layer management

  async _addScratchLayer(pointsGeoJSON) {
    try {
      if (!this.layers.scratchLayer && this.settings.scratchEnabled) {
        const ScratchLayer = await lazyLoader.loadLayer("scratch")
        this.layers.scratchLayer = new ScratchLayer(this.map, {
          visible: true,
          apiClient: this.api,
        })
        await this.layers.scratchLayer.add(pointsGeoJSON)
      } else if (this.layers.scratchLayer) {
        await this.layers.scratchLayer.update(pointsGeoJSON)
      }
    } catch (error) {
      console.warn("Failed to load scratch layer:", error)
    }
  }

  _addHeatmapLayer(pointsGeoJSON) {
    if (!this.layers.heatmapLayer) {
      this.layers.heatmapLayer = new HeatmapLayer(this.map, {
        visible:
          this.settings.heatmapEnabled &&
          !tiledPointsActive(SettingsManager.getSettings()),
      })
      this.layers.heatmapLayer.add(pointsGeoJSON)
    } else {
      this.layers.heatmapLayer.update(pointsGeoJSON)
    }
  }

  _addHexagonLayer() {
    if (this.layers.hexagonsLayer) return this.layers.hexagonsLayer

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Hard-reload the page (Cmd/Ctrl+Shift+R) — stale chunk references after a deploy are the most common cause
  2. Verify the scratch chunk exists in the current build output and matches the asset manifest
  3. If the chunk loads but still throws, reproduce with the error object expanded to find the failing line in ScratchLayer
  4. If the feature is not ready, disable scratchEnabled in settings until the build is fixed

Example fix

// before
const ScratchLayer = await lazyLoader.loadLayer("scratch")
// after
let ScratchLayer
try {
  ScratchLayer = await lazyLoader.loadLayer("scratch")
} catch (e) {
  if (String(e?.name).includes("ChunkLoadError")) {
    window.location.reload() // pick up freshly deployed chunk names
    return
  }
  throw e
}
Defensive patterns

Strategy: retry

Validate before calling

if (!this.settings.scratchEnabled) return // never import when the feature is off

Try / catch

try {
  const ScratchLayer = await lazyLoader.loadLayer("scratch")
  this.layers.scratchLayer = new ScratchLayer(this.map, { visible: true, apiClient: this.api })
  await this.layers.scratchLayer.add(pointsGeoJSON)
} catch (error) {
  if (String(error?.name).includes("ChunkLoadError")) {
    window.location.reload() // one reload picks up new chunk hashes after a deploy
    return
  }
  console.warn("Failed to load scratch layer:", error)
}

Prevention

When it happens

Trigger: A long-lived tab loading the scratch chunk after a deploy renamed chunk files (ChunkLoadError); a Vite/bundler misconfiguration dropping the scratch chunk from the build; an exception inside new ScratchLayer(...) or scratchLayer.add(pointsGeoJSON); scratchEnabled turned on on a build that lacks the layer code.

Common situations: Deploying while users have the map open; stale service-worker or CDN caches serving mixed asset versions; feature flag enabled before the code shipped; partial local builds during development.

Related errors


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