{"record":{"id":"601214265c2ac442","repo":"wagoodman/dive","slug":"path-does-not-exist-s","errorCode":null,"errorMessage":"path does not exist: %s","messagePattern":"path does not exist: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"dive/filetree/file_tree.go","lineNumber":236,"sourceCode":"\t\t\t\tfailed = append(failed, NewPathError(node.Path(), ActionRemove, err))\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tstackErr = upper.VisitDepthChildFirst(graft, nil)\n\treturn failed, stackErr\n}\n\n// GetNode fetches a single node when given a slash-delimited string from root ('/') to the desired node (e.g. '/a/node/path')\nfunc (tree *FileTree) GetNode(path string) (*FileNode, error) {\n\tnodeNames := strings.Split(strings.Trim(path, \"/\"), \"/\")\n\tnode := tree.Root\n\tfor _, name := range nodeNames {\n\t\tif name == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif node.Children[name] == nil {\n\t\t\treturn nil, fmt.Errorf(\"path does not exist: %s\", path)\n\t\t}\n\t\tnode = node.Children[name]\n\t}\n\treturn node, nil\n}\n\n// AddPath adds a new node to the tree with the given payload\nfunc (tree *FileTree) AddPath(filepath string, data FileInfo) (*FileNode, []*FileNode, error) {\n\tfilepath = path.Clean(filepath)\n\tif filepath == \".\" {\n\t\treturn nil, nil, fmt.Errorf(\"cannot add relative path '%s'\", filepath)\n\t}\n\tnodeNames := strings.Split(strings.Trim(filepath, \"/\"), \"/\")\n\tnode := tree.Root\n\taddedNodes := make([]*FileNode, 0)\n\tfor idx, name := range nodeNames {\n\t\tif name == \"\" {\n\t\t\tcontinue","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/wagoodman/dive/blob/d6c691947f8fda635c952a17ee3b7555379d58f0/dive/filetree/file_tree.go#L218-L254","documentation":"Returned (not panicked) by FileTree.GetNode (dive/filetree/file_tree.go:236). GetNode walks the children map segment by segment for a slash-delimited path; the moment a segment is missing from node.Children it returns 'path does not exist: %s'. It is the tree-walk equivalent of a failed map lookup.","triggerScenarios":"Calling GetNode with a path whose first differing segment is absent - e.g. '/etc/nginx' when the tree has no 'etc' child; querying a path that only exists in a different (later) layer before those layers are stacked; typos or non-normalized input ('/etc//nginx' is tolerated by the empty-segment skip, but '/etc/./nginx' is not - '.' is looked up literally).","commonSituations":"Writing tooling on top of dive's filetree that probes for files by absolute path, then probing a path from a layer that was deleted (whiteout) or that was never added; querying the wrong tree object (per-layer tree instead of the stacked analysis tree).","solutions":["Check the path against the stacked/analysis tree, not an individual layer tree","Normalize input first: path.Clean on the query, and remember segments are matched literally","Handle the error as an expected 'not found' rather than a failure - this is a sentinel-style lookup miss","Verify the path actually exists in the image: dive <image> then search for the file in the UI to confirm which tree holds it"],"exampleFix":"// before: assuming the node exists\nnode, _ := tree.GetNode(\"/etc/nginx/nginx.conf\") // nil node + swallowed error -> later nil deref\n\n// after: treat miss as a case\nnode, err := tree.GetNode(path.Clean(p))\nif err != nil {\n    return fmt.Errorf(\"file not present in this tree: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// normalize before lookup\nq := path.Clean(p)\nif !strings.HasPrefix(q, \"/\") {\n    q = \"/\" + q\n}\nnode, err := tree.GetNode(q)\nif err != nil { /* expected miss */ }","typeGuard":null,"tryCatchPattern":"node, err := tree.GetNode(target)\nif err != nil {\n    if strings.Contains(err.Error(), \"path does not exist\") {\n        // treat as not-found, not a failure\n        return nil, nil\n    }\n    return nil, fmt.Errorf(\"lookup %q: %w\", target, err)\n}","preventionTips":["Always path.Clean the query and force a leading '/'","Query the stacked analysis tree, not per-layer trees, when checking for image files","Treat GetNode's error as a sentinel 'not found' and handle it explicitly"],"tags":["filetree","lookup","path","api-contract"],"backgroundTag":null,"analyzedSha":"d6c691947f8fda635c952a17ee3b7555379d58f0","analyzedAt":"2026-08-15T09:42:35.293Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}