alibaba/spring-ai-alibaba · warning · IOException

Path outside root directory:

Error message

Path outside root directory: 

What it means

After resolving and normalizing the virtual path against rootPath, GlobSearchTool.validateAndResolvePath() throws IOException "Path outside root directory: <path>" when the normalized full path does not start with the root. This is the second line of defense after the literal .. check, catching symlink/normalization escapes.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/tools/GlobSearchTool.java:178

	private Path validateAndResolvePath(String path) throws IOException {
		// Normalize path
		if (!path.startsWith("/")) {
			path = "/" + path;
		}

		// Check for path traversal
		if (path.contains("..") || path.contains("~")) {
			throw new IOException("Path traversal not allowed");
		}

		// Convert virtual path to filesystem path
		String relative = path.substring(1); // Remove leading /
		Path fullPath = rootPath.resolve(relative).normalize();

		// Ensure path is within root
		if (!fullPath.startsWith(rootPath)) {
			throw new IOException("Path outside root directory: " + path);
		}

		return fullPath;
	}

	private record FileInfo(String path, Instant modifiedTime) {}

	public static Builder builder(String rootPath) {
		return new Builder(rootPath);
	}

	public static class Builder {

		private final String rootPath;

		private String name = "glob_search";

		private String description = "Fast file pattern matching tool that works with any codebase size. "

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Pass paths that resolve within the configured root directory.
  2. Ensure rootPath is absolute and toRealPath()-normalized so symlink resolution matches the check.
  3. Remove or re-point symlinks inside the root that escape the workspace.
  4. Catch IOException and surface a tool error prompting the model to use a valid path.

Example fix

// before
Path root = Paths.get("workspace"); // relative — checks may misalign
// after
Path root = Paths.get("workspace").toAbsolutePath().normalize();
Defensive patterns

Strategy: validation

Validate before calling

Path root = Paths.get(rootDir).toAbsolutePath().normalize();
Path target = root.resolve(relPath).normalize();
if (!target.startsWith(root)) { throw new IllegalArgumentException("path escapes root"); }

Type guard

boolean insideRoot(Path root, Path p) { return p.toAbsolutePath().normalize().startsWith(root.toAbsolutePath().normalize()); }

Try / catch

try { tool.glob(pattern, path); } catch (IOException e) { if (e.getMessage().startsWith("Path outside root")) { /* retry with root-relative path */ } }

Prevention

When it happens

Trigger: A path that normalizes outside rootPath — e.g. through symlinks inside the root pointing elsewhere, or encodings/tricks that survive the ".." substring check but resolve outside.

Common situations: Symlinked subdirectories in the workspace pointing to other locations, misconfigured rootPath (relative paths resolved differently than expected), tools called with paths intended for a different tool instance.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/5d7d2e73628f584b. Report an issue: GitHub.