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
- 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").
- Normalize/resolve paths in your own code before invoking the tool and reject ones that escape the root.
- 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
- Sanitize LLM-generated tool arguments before invoking filesystem tools.
- Always express paths relative to the tool root; never pass ../ or ~ forms.
- Document the sandbox root to the model in its system prompt so it requests in-root paths.
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
- Path: outside root directory:
- 非法路径访问尝试: ${path}
- Path traversal not allowed
- Path traversal not allowed:
- Path traversal not allowed
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/a4fee727418d0fbb.
Report an issue: GitHub.