{"record":{"id":"e628799baac0f11e","repo":"wagoodman/dive","slug":"unable-to-propagate-tree-on-cursorleft-w","errorCode":null,"errorMessage":"unable to propagate tree on cursorLeft: %w","messagePattern":"unable to propagate tree on cursorLeft: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/dive/cli/internal/ui/v1/viewmodel/filetree.go","lineNumber":202,"sourceCode":"\t\tif strings.Compare(parentPath, curNode.Path()) == 0 {\n\t\t\tnewIndex = dfsCounter\n\t\t}\n\t\tdfsCounter++\n\t\treturn nil\n\t}\n\n\tevaluator = func(curNode *filetree.FileNode) bool {\n\t\tregexMatch := true\n\t\tif filterRegex != nil {\n\t\t\tmatch := filterRegex.Find([]byte(curNode.Path()))\n\t\t\tregexMatch = match != nil\n\t\t}\n\t\treturn !curNode.Parent.Data.ViewInfo.Collapsed && !curNode.Data.ViewInfo.Hidden && regexMatch\n\t}\n\n\terr := vm.ModelTree.VisitDepthParentFirst(visitor, evaluator)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to propagate tree on cursorLeft: %w\", err)\n\t}\n\n\tvm.TreeIndex = newIndex\n\tmoveIndex := oldIndex - newIndex\n\tif newIndex < vm.bufferIndexLowerBound {\n\t\tvm.bufferIndexLowerBound = vm.TreeIndex\n\t}\n\n\tif vm.bufferIndex > moveIndex {\n\t\tvm.bufferIndex -= moveIndex\n\t} else {\n\t\tvm.bufferIndex = 0\n\t}\n\n\treturn nil\n}\n\n// CursorRight descends into directory expanding it if needed","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/wagoodman/dive/blob/d6c691947f8fda635c952a17ee3b7555379d58f0/cmd/dive/cli/internal/ui/v1/viewmodel/filetree.go#L184-L220","documentation":"CursorLeft walks the model tree parent-first to recompute the index of the current node's parent (jump-to-parent navigation) and wraps any traversal error. As in other spots, the visitor closure returns nil unconditionally, so this wrap is defensive and essentially unreachable unless the traversal itself fails on structurally invalid tree state.","triggerScenarios":"vm.ModelTree.VisitDepthParentFirst returning an error during a left-arrow press; the closure only records an index and never errors, so this needs an invalid tree (broken links/nil nodes) or fork-modified traversal.","commonSituations":"Not observed with stock dive; conceivable in forks that mutate the tree during navigation or under concurrent tree access from filter-edit listeners.","solutions":["In stock dive, report upstream with the wrapped error chain","In forks, avoid mutating ModelTree inside visitor closures or concurrently with key handling","Reproduce with filtering disabled (no regex evaluator path) to isolate the cause","Re-analyze the image to rebuild clean trees"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := vm.CursorLeft(filterRegex); err != nil {\n    // navigation is non-critical: log and keep prior cursor state\n    log.WithFields(\"error\", err).Debug(\"cursorLeft failed\")\n}","preventionTips":["Never mutate the tree inside navigation visitors","Guard against nil nodes when reading Parent links"],"tags":["filetree","navigation","traversal","defensive"],"backgroundTag":null,"analyzedSha":"d6c691947f8fda635c952a17ee3b7555379d58f0","analyzedAt":"2026-08-15T09:42:35.293Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}