apple/pkl · error · SecurityManagerException
resourcePastRootDir|modulePastRootDir
resourcePastRootDir|modulePastRootDir
Error message
resourcePastRootDir|modulePastRootDir
What it means
When resolving file/resource URIs, the security manager canonicalizes the target path with toRealPath (following symlinks) and rejects it if it escapes the configured root directory. The error key is `resourcePastRootDir` for resources and `modulePastRootDir` for modules, guarding against path-traversal outside the sandbox root.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/SecurityManagers.java:189
throw new SecurityManagerException(message);
}
}
@Override
public @Nullable Path resolveSecurePath(URI uri, boolean isResource)
throws SecurityManagerException, IOException {
if (rootDir == null
|| !uri.isAbsolute()
|| !uri.getScheme().equals("file")
|| (uri.getAuthority() != null && !uri.getAuthority().isEmpty())) {
return null;
}
var path = Path.of(uri);
var realPath = path.toRealPath();
if (!realPath.startsWith(rootDir)) {
var errorMessageKey = isResource ? "resourcePastRootDir" : "modulePastRootDir";
var message = ErrorMessages.create(errorMessageKey, uri, rootDir);
throw new SecurityManagerException(message);
}
return realPath;
}
private @Nullable Path normalizePath(@Nullable Path path) {
if (path == null) {
return null;
}
try {
if (Files.exists(path)) {
return path.toRealPath();
}
return path.toAbsolutePath();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Keep modules/resources physically inside the configured root directory (copy or move them in)
- Remove or re-point symlinks that escape the root
- Correct the URI to a path within rootDir instead of using traversal segments
Example fix
// before import "../shared/config.pkl" // after (within root) import "shared/config.pkl"
Defensive patterns
Strategy: validation
Validate before calling
java.nio.file.Path target = java.nio.file.Path.of(uri).toRealPath();
if (!target.startsWith(rootDir)) throw new IllegalArgumentException("path escapes root: " + uri); Try / catch
try {
Path real = resolveSecurePath(uri, isResource);
} catch (SecurityManagerException e) {
// remap the URI to a path inside rootDir or copy the file into root
} Prevention
- Avoid `..` segments and out-of-root symlinks in module/resource paths
- Keep all modules and resources within the configured root directory
- Re-check paths after restructuring directories or changing rootDir
When it happens
Trigger: Calling resolveSecurePath with a URI whose real path does not start with rootDir — e.g. `../` traversal in a path, or a symlink pointing outside the root — during module or resource loading.
Common situations: Symlinked module files pointing to locations outside the project root; paths containing `..` segments that resolve outside root; moving/renaming the root directory so previously valid paths now resolve elsewhere.
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
- insufficientModuleTrustLevel
- resourceNotInAllowList|moduleNotInAllowList
- No security manager set.
- Is a directory
- invalidPackageZipChecksum
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/378c8d9923a08a61.
Report an issue: GitHub.