{"record":{"id":"aea61c48e85f1c04","repo":"googleapis/mcp-toolbox","slug":"path-q-cannot-be-resolved-w","errorCode":null,"errorMessage":"path %q cannot be resolved: %w","messagePattern":"path %q cannot be resolved: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/cloudstorage/cloudstoragecommon/paths.go","lineNumber":152,"sourceCode":"\n\tcleanDest := filepath.Clean(filepath.Join(cleanDir, rel))\n\tout, err := escapes(cleanDir, cleanDest)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"path %q cannot be resolved within %q: %w\", rel, cleanDir, err)\n\t}\n\tif out {\n\t\treturn \"\", fmt.Errorf(\"path %q escapes configured directory %q\", rel, cleanDir)\n\t}\n\n\t// Repeat the check against the real targets. A symlink under cleanDir can\n\t// point anywhere, so the name-level check above proves nothing on its own.\n\tresolvedDir, err := ResolveSymlinks(cleanDir)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"directory %q cannot be resolved: %w\", cleanDir, err)\n\t}\n\tresolvedDest, err := ResolveSymlinks(cleanDest)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"path %q cannot be resolved: %w\", rel, err)\n\t}\n\tout, err = escapes(resolvedDir, resolvedDest)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"path %q cannot be resolved within %q: %w\", rel, cleanDir, err)\n\t}\n\tif out {\n\t\treturn \"\", fmt.Errorf(\"path %q resolves through a symbolic link to a target outside configured directory %q\", rel, cleanDir)\n\t}\n\treturn cleanDest, nil\n}\n","sourceCodeStart":134,"sourceCodeEnd":163,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/cloudstorage/cloudstoragecommon/paths.go#L134-L163","documentation":"ResolveWithinDir verifies that a user-supplied relative path stays inside an allowed directory after symlink resolution. This error is returned when the destination path cannot be resolved via filepath.EvalSymlinks/ResolveSymlinks (e.g. broken symlink, permission failure, path not existing in a way EvalSymlinks rejects). The underlying OS error is wrapped with %w so the root cause (ENOENT, EACCES, ELOOP) is preserved.","triggerScenarios":"Calling ResolveWithinDir (directly or via a cloud-storage tool's Invoke) with a 'dest' path containing a dangling symlink or an unreadable path component so ResolveSymlinks(cleanDest) returns an error.","commonSituations":"User provides a destination object path that includes a symlink pointing to a deleted file; running as a service account lacking execute permission on a directory component; container volumes with stale symlinks after a restart.","solutions":["Inspect the wrapped %w cause with errors.Unwrap/errors.Is to identify the OS error (ENOENT/EACCES/ELOOP)","Remove or repair the dangling symlink at the destination path","Ensure the process has read+execute permission on every directory component of the path","Re-check the path with `ls -la` / `readlink -f` on the host before retrying"],"exampleFix":"// before\nresolvedDest, err := ResolveSymlinks(cleanDest) // fails: dangling symlink\n// after\nif _, err := os.Lstat(cleanDest); err == nil {\n    if fi, err := os.Stat(cleanDest); err != nil && os.IsNotExist(err) {\n        os.Remove(cleanDest) // remove dangling symlink before resolving\n    }\n}\nresolvedDest, err := ResolveSymlinks(cleanDest)","handlingStrategy":"validation","validationCode":"func pathResolvable(p string) error {\n    if _, err := filepath.EvalSymlinks(p); err != nil {\n        return fmt.Errorf(\"path %q not resolvable: %w\", p, err)\n    }\n    return nil\n}\nif err := pathResolvable(dest); err != nil { return err }","typeGuard":"func isSymlink(p string) bool {\n    fi, err := os.Lstat(p)\n    return err == nil && fi.Mode()&os.ModeSymlink != 0\n}","tryCatchPattern":"resolved, err := ResolveWithinDir(baseDir, userPath)\nif err != nil {\n    var perr *os.PathError\n    if errors.As(err, &perr) { log.Printf(\"OS cause: %v\", perr.Err) }\n    return fmt.Errorf(\"invalid destination: %w\", err)\n}","preventionTips":["Lstat the path before use to detect dangling symlinks","Ensure service account has traverse (x) permission on all parent dirs","Clean up stale symlinks in shared volumes after restarts","Log errors.Unwrap chains to capture the OS-level cause"],"tags":["filesystem","symlink","path-resolution","security"],"backgroundTag":"symlink-resolution-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}