wagoodman/dive · error

invalid layer index given: %d of %d

Error message

invalid layer index given: %d of %d

What it means

SetTreeByLayer guards the requested top-layer index against the number of analyzed layer trees (len(vm.RefTrees)-1) and rejects any index above the last valid one. The message shows 'requested of lastValidIndex'. It fires when the UI or CLI asks the filetree to display a layer that does not exist in the current image analysis.

Source

Thrown at cmd/dive/cli/internal/ui/v1/viewmodel/filetree.go:111

	return vm.bufferIndexLowerBound + vm.height()
}

// IsVisible indicates if the file tree view pane is currently initialized
func (vm *FileTreeViewModel) IsVisible() bool {
	return vm != nil
}

// ResetCursor moves the cursor back to the top of the buffer and translates to the top of the buffer.
func (vm *FileTreeViewModel) ResetCursor() {
	vm.TreeIndex = 0
	vm.bufferIndex = 0
	vm.bufferIndexLowerBound = 0
}

// SetTreeByLayer populates the view model by stacking the indicated image layer file trees.
func (vm *FileTreeViewModel) SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) error {
	if topTreeStop > len(vm.RefTrees)-1 {
		return fmt.Errorf("invalid layer index given: %d of %d", topTreeStop, len(vm.RefTrees)-1)
	}
	newTree, err := vm.comparer.GetTree(filetree.NewTreeIndexKey(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop))
	if err != nil {
		return fmt.Errorf("unable to fetch layer tree from cache: %w", err)
	}

	// preserve vm state on copy
	visitor := func(node *filetree.FileNode) error {
		newNode, err := newTree.GetNode(node.Path())
		if err == nil {
			newNode.Data.ViewInfo = node.Data.ViewInfo
		}
		return nil
	}
	err = vm.ModelTree.VisitDepthChildFirst(visitor, nil)
	if err != nil {
		return fmt.Errorf("unable to propagate layer tree: %w", err)
	}

View on GitHub (pinned to d6c691947f)

Solutions

  1. Clamp the requested index to len(RefTrees)-1 (or 0) before calling SetTreeByLayer
  2. If selecting via UI, ensure the layer list view and the filetree viewmodel share the same RefTrees snapshot
  3. Verify the image actually has that many layers: docker history <image> or dive's layer pane
  4. For embedding code, pass initialLayer within bounds when constructing the viewmodel

Example fix

// before
err := vm.SetTreeByLayer(0, 0, requestedLayer, requestedLayer)
// after
if requestedLayer > len(vm.RefTrees)-1 {
    requestedLayer = len(vm.RefTrees) - 1
}
err := vm.SetTreeByLayer(0, 0, requestedLayer, requestedLayer)
Defensive patterns

Strategy: validation

Validate before calling

// bounds-check before calling SetTreeByLayer
maxIdx := len(vm.RefTrees) - 1
if topTreeStop > maxIdx { topTreeStop = maxIdx }
if topTreeStart > maxIdx { topTreeStart = maxIdx }

Try / catch

if err := vm.SetTreeByLayer(b0, b1, t0, t1); err != nil {
    if strings.Contains(err.Error(), "invalid layer index given") {
        // clamp and retry once
        err = vm.SetTreeByLayer(b0, b1, len(vm.RefTrees)-1, len(vm.RefTrees)-1)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling SetTreeByLayer with topTreeStop > len(RefTrees)-1: selecting a layer index beyond the image's layer count (e.g. initial layer selection from config/CLI, or a listener passing a stale index after the image analysis changed), and edge cases with single-layer images where any index > 0 is invalid.

Common situations: Passing a layer index meant for a different image; scripts embedding the viewmodel that hardcode layer indexes; images with fewer layers than expected (single-stage scratch images); races where RefTrees is swapped while a layer selection is in flight.

Related errors


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