wagoodman/dive · error

error notifying layer change listeners: %w

Error message

error notifying layer change listeners: %w

What it means

Layer.notifyLayerChangeListeners broadcasts a LayerSelection (current layer plus compare index bounds) to registered listeners — mainly the filetree view, which responds by calling SetTree for the newly selected layer. If any listener returns an error, it is wrapped here. In practice the wrapped error is usually a filetree failure such as 'invalid layer index given' or 'unable to fetch layer tree from cache'.

Source

Thrown at cmd/dive/cli/internal/ui/v1/view/layer.go:76

}

func (v *Layer) AddLayerChangeListener(listener ...LayerChangeListener) {
	v.listeners = append(v.listeners, listener...)
}

func (v *Layer) notifyLayerChangeListeners() error {
	bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop := v.vm.GetCompareIndexes()
	selection := viewmodel.LayerSelection{
		Layer:           v.CurrentLayer(),
		BottomTreeStart: bottomTreeStart,
		BottomTreeStop:  bottomTreeStop,
		TopTreeStart:    topTreeStart,
		TopTreeStop:     topTreeStop,
	}
	for _, listener := range v.listeners {
		err := listener(selection)
		if err != nil {
			return fmt.Errorf("error notifying layer change listeners: %w", err)
		}
	}
	// this is hacky, and I do not like it
	if layerDetails, err := v.gui.View("layerDetails"); err == nil {
		if err := layerDetails.SetCursor(0, 0); err != nil {
			v.logger.Debug("Couldn't set cursor to 0,0 for layerDetails")
		}
	}
	return nil
}

func (v *Layer) Name() string {
	return v.name
}

// Setup initializes the UI concerns within the context of a global [gocui] view object.
func (v *Layer) Setup(body *gocui.View, header *gocui.View) error {
	v.logger.Trace("Setup()")

View on GitHub (pinned to d6c691947f)

Solutions

  1. Read the wrapped error — it carries the real cause (usually filetree/comparer); fix that first
  2. Re-run analysis on the image; transient tarball fetch issues during image load can produce broken ref trees
  3. Try the other compare mode (layer vs aggregated) to see if the failure is mode-specific
  4. Report upstream with the image reference and full wrapped error if reproducible
Defensive patterns

Strategy: try-catch

Validate before calling

// clamp selection to valid layer range before notifying listeners
if selection.LayerIdx > len(refTrees)-1 { selection.LayerIdx = len(refTrees) - 1 }

Try / catch

if err := v.notifyLayerChangeListeners(); err != nil {
    // layer selection succeeded; degrade gracefully
    v.logger.WithFields("error", err).Warn("layer change listener failed")
}

Prevention

When it happens

Trigger: Changing the selected layer (arrow keys in the layer pane) causing a listener to fail: the filetree's SetTreeByLayer receiving out-of-range indexes, comparer cache fetch errors, or tree propagation/visit errors bubbling up through the listener chain.

Common situations: Navigating layers of an image whose analysis produced inconsistent RefTrees; selecting an aggregated view with edge-case layer counts (single-layer images); corrupted/unusual OCI layers that fail tree stacking when the selection changes.

Related errors


AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15). Data as JSON: /api/errors/67b112c6af50f3a0. Report an issue: GitHub.