alibaba/spring-ai-alibaba · error · IllegalArgumentException

Path traversal not allowed

Error message

Path traversal not allowed

What it means

FileSystemTools resolves every tool path through resolvePath, which applies security checks. In virtual mode, any path containing ".." or starting with "~" is rejected with "Path traversal not allowed" to prevent escaping the tool's root directory. This is an intentional security guard, not a bug.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/extension/tools/filesystem/FileSystemTools.java:76

	 * 
	 * @param rootDir Optional root directory for file operations
	 * @param virtualMode When true, treat incoming paths as virtual absolute paths under cwd
	 * @param maxFileSizeMb Maximum file size in MB for reading operations
	 */
	public FileSystemTools(String rootDir, boolean virtualMode, int maxFileSizeMb) {
		this.cwd = rootDir != null ? Paths.get(rootDir).toAbsolutePath().normalize() : Paths.get("").toAbsolutePath();
		this.virtualMode = virtualMode;
		this.maxFileSizeBytes = maxFileSizeMb * 1024L * 1024L;
	}

	/**
	 * Resolve a file path with security checks.
	 */
	private Path resolvePath(String key) throws IllegalArgumentException {
		if (virtualMode) {
			String vpath = key.startsWith("/") ? key : "/" + key;
			if (vpath.contains("..") || vpath.startsWith("~")) {
				throw new IllegalArgumentException("Path traversal not allowed");
			}
			Path full = cwd.resolve(vpath.substring(1)).normalize();
			if (!full.startsWith(cwd)) {
				throw new IllegalArgumentException("Path:" + full + " outside root directory: " + cwd);
			}
			return full;
		}

		Path path = Paths.get(key);
		if (path.isAbsolute()) {
			return path;
		}
		return cwd.resolve(path).normalize();
	}

	// @formatter:off
	@Tool(name = "read_file", description = """
		Reads a file from the filesystem. You can access any file directly by using this tool.

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Rewrite the requested path to be relative to the tool's root directory without .. segments (e.g., use "docs/file.txt" instead of "../docs/file.txt").
  2. Normalize/resolve paths in your own code before invoking the tool and reject ones that escape the root.
  3. Do not prefix paths with ~; pass absolute-from-root virtual paths like "/home/user/file.txt" if the virtual FS layout expects it.

Example fix

// before
String path = "../../etc/passwd"; // rejected: Path traversal not allowed
// after
String path = "/etc/passwd"; // only if inside the configured root; otherwise use a path within cwd, e.g. "data/file.txt"
Defensive patterns

Strategy: validation

Validate before calling

String normalized = Paths.get(key).normalize().toString();
if (normalized.contains("..") || normalized.startsWith("~")) {
    throw new IllegalArgumentException("Refusing to use path outside sandbox: " + key);
}

Type guard

static boolean isSafePath(String key) {
    String v = key.startsWith("/") ? key : "/" + key;
    return !v.contains("..") && !v.startsWith("~");
}

Try / catch

try {
    fsTool.read(path);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Path traversal")) {
        log.warn("Rejected unsafe path argument: {}", path);
    }
}

Prevention

When it happens

Trigger: A filesystem tool call (read/write/ls/glob etc.) receives a key like "../secret.txt", "a/../../etc/passwd", or "~/notes.md" while running in virtualMode.

Common situations: An LLM-generated tool argument includes ../ to reach files outside its sandbox; shell-style ~ expansion assumed to work; path joins built from user input that weren't normalized before the tool call.

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/a4fee727418d0fbb. Report an issue: GitHub.