wagoodman/dive · error

unable to propagate vm view tree: %w

Error message

unable to propagate vm view tree: %w

What it means

After Update copies ModelTree to ViewTree, it prunes hidden nodes with VisitDepthParentFirst + RemovePath and wraps any failure here. Because the traversal is parent-first, RemovePath can be called on a hidden directory while its children still exist — the classic way to hit this is a tree where a parent is hidden but children remain in the copy, making RemovePath fail. This is a real (if rare) error path, unlike the defensive visitor wraps.

Source

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

	if err != nil {
		return fmt.Errorf("unable to propagate vm model tree: %w", err)
	}

	// make a new tree with only visible nodes
	vm.ViewTree = vm.ModelTree.Copy()
	err = vm.ViewTree.VisitDepthParentFirst(func(node *filetree.FileNode) error {
		if node.Data.ViewInfo.Hidden {
			err1 := vm.ViewTree.RemovePath(node.Path())
			if err1 != nil {
				return err1
			}
		}
		return nil
	}, nil)

	if err != nil {
		return fmt.Errorf("unable to propagate vm view tree: %w", err)
	}

	return nil
}

// Render flushes the state objects (file tree) to the pane.
func (vm *FileTreeViewModel) Render() error {
	treeString := vm.ViewTree.StringBetween(vm.bufferIndexLowerBound, vm.bufferIndexUpperBound(), vm.ShowAttributes)
	lines := strings.Split(treeString, "\n")

	// update the contents
	vm.Buffer.Reset()
	for idx, line := range lines {
		if idx == vm.bufferIndex {
			_, err := fmt.Fprintln(&vm.Buffer, format.Selected(vtclean.Clean(line, false)))
			if err != nil {
				return err
			}

View on GitHub (pinned to d6c691947f)

Solutions

  1. Toggle the hidden diff types back on (Ctrl+R style bindings) to restore a consistent tree and retry
  2. Clear the path filter if one is active, then re-apply — it recomputes hidden flags coherently
  3. If embedding/forking, prune child-first (VisitDepthChildFirst) so children are removed before parents
  4. Report upstream if reproducible in stock dive with the filter/hide combination used

Example fix

// before: parent-first pruning can remove a dir before its hidden children
err := vm.ViewTree.VisitDepthParentFirst(visitor, nil)
// after: child-first so children are pruned before their parents
err := vm.ViewTree.VisitDepthChildFirst(visitor, nil)
Defensive patterns

Strategy: fallback

Validate before calling

// prune child-first so children are removed before parents
cfg := filetree.VisitDepthChildFirst // ordering that avoids RemovePath-with-children errors

Try / catch

err := vm.ViewTree.VisitDepthParentFirst(pruneVisitor, nil)
if err != nil {
    // fall back: flag hidden nodes instead of pruning so rendering still works
    vm.ViewTree = vm.ModelTree.Copy()
}

Prevention

When it happens

Trigger: vm.ViewTree.RemovePath(node.Path()) returning an error during pruning: removing a node that still has children (parent-first order guarantees parents are visited before their hidden children are removed), or the path no longer resolving after earlier removals in the same pass.

Common situations: Aggressive hiding: hiding 'unmodified' or 'modified' diff types on large trees where entire directories qualify; combining a path filter with diff-type hiding so parent/child hidden flags diverge; deep directory trees where parent-first removal ordering matters.

Related errors


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