googleapis/mcp-toolbox · error

path %q traverses unresolvable symbolic link %q

Error message

path %q traverses unresolvable symbolic link %q

What it means

While walking up to the deepest existing ancestor, ResolveSymlinks found a path component that exists as a symlink but does not resolve (a dangling link); creating a file there would follow the link, reopening the escape this check exists to close, so it is rejected.

Source

Thrown at internal/tools/cloudstorage/cloudstoragecommon/paths.go:90

// caller that opens the path afterwards is still racing anyone able to write
// into the directories it traverses. Hard links are not detectable here at all.
// Both remain the operator's to contain with OS permissions.
func ResolveSymlinks(path string) (string, error) {
	resolved, err := filepath.EvalSymlinks(path)
	if err == nil {
		return resolved, nil
	}
	if !errors.Is(err, fs.ErrNotExist) {
		return "", fmt.Errorf("cannot resolve path %q: %w", path, err)
	}

	// Walk up to the deepest ancestor that does resolve, remembering the
	// components we stepped over so they can be reattached to it.
	var missing []string
	cur := path
	for {
		if fi, lerr := os.Lstat(cur); lerr == nil && fi.Mode()&fs.ModeSymlink != 0 {
			return "", fmt.Errorf("path %q traverses unresolvable symbolic link %q", path, cur)
		}
		parent := filepath.Dir(cur)
		if parent == cur {
			return "", fmt.Errorf("cannot resolve path %q: no existing ancestor", path)
		}
		missing = append([]string{filepath.Base(cur)}, missing...)
		cur = parent

		resolvedParent, perr := filepath.EvalSymlinks(cur)
		if perr == nil {
			return filepath.Join(append([]string{resolvedParent}, missing...)...), nil
		}
		if !errors.Is(perr, fs.ErrNotExist) {
			return "", fmt.Errorf("cannot resolve path %q: %w", path, perr)
		}
	}
}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Remove or repair the dangling symlink named in the error
  2. Point the symlink at an existing target inside the allowed area
  3. Use a path that avoids the broken link
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/tools/cloudstorage/cloudstoragecommon/paths.go:90 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/b69284534cdca70b. Report an issue: GitHub.