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
- Clamp the requested index to len(RefTrees)-1 (or 0) before calling SetTreeByLayer
- If selecting via UI, ensure the layer list view and the filetree viewmodel share the same RefTrees snapshot
- Verify the image actually has that many layers: docker history <image> or dive's layer pane
- 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
- Always clamp UI-selected indexes to len(RefTrees)-1
- Share one immutable RefTrees snapshot between views
- Unit-test single-layer images (maxIdx == 0)
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
- unknown diff.hide value: %s
- invalid %s config value, given %q: %v
- %s config value is outside allowed range (0-1), given '%f'
- invalid highestWastedBytes config value, given %q: %v
- invalid highestUserWastedPercent config value, given %q: %v
AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15).
Data as JSON: /api/errors/73025f5f18051e07.
Report an issue: GitHub.