wagoodman/dive · warning

cannot add relative path '%s'

Error message

cannot add relative path '%s'

What it means

Returned by FileTree.AddPath (dive/filetree/file_tree.go:247). AddPath runs path.Clean on the input and rejects the result '.', which is what Clean produces for empty strings, '.', './' and repeated slashes. The tree is rooted; you must add absolute-style paths.

Source

Thrown at dive/filetree/file_tree.go:247

	nodeNames := strings.Split(strings.Trim(path, "/"), "/")
	node := tree.Root
	for _, name := range nodeNames {
		if name == "" {
			continue
		}
		if node.Children[name] == nil {
			return nil, fmt.Errorf("path does not exist: %s", path)
		}
		node = node.Children[name]
	}
	return node, nil
}

// AddPath adds a new node to the tree with the given payload
func (tree *FileTree) AddPath(filepath string, data FileInfo) (*FileNode, []*FileNode, error) {
	filepath = path.Clean(filepath)
	if filepath == "." {
		return nil, nil, fmt.Errorf("cannot add relative path '%s'", filepath)
	}
	nodeNames := strings.Split(strings.Trim(filepath, "/"), "/")
	node := tree.Root
	addedNodes := make([]*FileNode, 0)
	for idx, name := range nodeNames {
		if name == "" {
			continue
		}
		// find or create node
		if node.Children[name] != nil {
			node = node.Children[name]
		} else {
			// don't add paths that should be deleted
			if strings.HasPrefix(name, doubleWhiteoutPrefix) {
				return nil, addedNodes, nil
			}

			// don't attach the payload. The payload is destined for the

View on GitHub (pinned to d6c691947f)

Solutions

  1. Pass clean absolute-style paths: strings like "/app/bin/tool", not "./app/bin/tool" or ""
  2. Filter degenerate tar/walk entries before building the tree: if path.Clean(name) == "." { continue }
  3. At the call site, keep using filepath.Join("/", name) to force an absolute form for relative inputs

Example fix

// before
_, _, err := tree.AddPath(relName, info) // relName == "./" or "" from a tar header

// after
if cleaned := path.Clean(relName); cleaned == "." {
    continue // skip root-alias entries
}
tree.AddPath("/"+strings.TrimPrefix(cleaned, "/"), info)
Defensive patterns

Strategy: validation

Validate before calling

// reject/normalize degenerate inputs before AddPath
cleaned := path.Clean(p)
if cleaned == "." {
    return nil // or: skip when filtering tar entries
}
cleaned = "/" + strings.TrimPrefix(cleaned, "/")
node, added, err := tree.AddPath(cleaned, data)

Try / catch

node, added, err := tree.AddPath(p, data)
if err != nil && strings.Contains(err.Error(), "cannot add relative path") {
    // normalize and retry once with an absolute path
    node, added, err = tree.AddPath("/"+strings.TrimPrefix(path.Clean(p), "/"), data)
}

Prevention

When it happens

Trigger: Calling AddPath("", ".", or "./") - anything that cleans to the root itself; also a computed relative filename from a tar header or walk that is empty after trimming slashes.

Common situations: Feeding tar entries with degenerate names ("./" entries some builders emit), or passing a relative path where an absolute one was expected when building trees programmatically.

Related errors


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