apple/pkl · error · VmException
cannotResolveTripleDotImports
cannotResolveTripleDotImports
Error message
Cannot resolve a triple-dot import from module URI `{0}`. What it means
Triple-dot imports (import "...") resolve relative to the enclosing project/package root. This eval error is thrown when the module performing the triple-dot import is not a local module with hierarchical URIs, so the '...' root cannot be computed.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/util/IoUtils.java:376
public static URI resolve(ReaderBase reader, URI baseUri, String importUri) {
return resolve(reader, baseUri, createUri(importUri));
}
public static URI resolve(ReaderBase reader, URI baseUri, URI importUri) {
if (reader.hasFragmentPaths() && !importUri.isAbsolute() && importUri.getPath() != null) {
var fragment = baseUri.getFragment();
var newFragment = resolve(createUri(fragment), importUri);
return stripFragment(baseUri).resolve("#" + newFragment);
}
return resolve(baseUri, importUri);
}
private static URI resolveTripleDotImport(
SecurityManager securityManager, ModuleKey moduleKey, String tripleDotPath)
throws IOException, SecurityManagerException, ExternalReaderProcessException {
var moduleKeyUri = moduleKey.getUri();
if (!moduleKey.isLocal() || !moduleKey.hasHierarchicalUris()) {
throw new VmExceptionBuilder()
.evalError("cannotResolveTripleDotImports", moduleKeyUri)
.build();
}
var currentPath =
moduleKey.hasFragmentPaths() ? moduleKeyUri.getFragment() : moduleKeyUri.getPath();
var effectiveImportPath =
tripleDotPath.isEmpty()
? currentPath.substring(currentPath.lastIndexOf('/') + 1)
: tripleDotPath;
var index = currentPath.lastIndexOf('/');
index = currentPath.lastIndexOf('/', index - 1);
var basePath = currentPath;
while (index > 0) {
basePath = basePath.substring(0, index + 1);
var candidatePath = basePath + effectiveImportPath;
// make sure triple-dot cannot resolve to the same path.
var candidateUri = resolve(moduleKey, moduleKeyUri, candidatePath);View on GitHub (pinned to f3efcbfc9b)
Solutions
- Move the import so it is only used in local files on disk
- Use a fully-qualified package or absolute URI import instead of triple-dot in remote modules
- If the module should be local, load it via a file: URI
Example fix
// before (inside an http-served module) import ".../my_module.pkl" // after import "@my_package/my_module.pkl"
Defensive patterns
Strategy: validation
Validate before calling
if (importPath.startsWith("...") && !moduleUri.getScheme().equals("file")) {
throw new IllegalArgumentException("triple-dot import only valid in local modules");
} Type guard
function supportsTripleDot(key) { return key.isLocal() && key.hasHierarchicalUris(); } Try / catch
try { resolveTripleDotImport(...) } catch (VmException e) { logger.error(e.getMessage()); } Prevention
- Only use `import "..."` in modules on the local filesystem
- Prefer package imports (@name) for remote modules
- Keep triple-dot imports in project-local source trees
When it happens
Trigger: resolveTripleDotImport is invoked with a moduleKey that is remote (http:, package:, project:) or otherwise lacks hierarchical URIs, e.g. `import "..."` inside a module fetched from an HTTP URL or loaded from a package.
Common situations: Writing `import ".../foo.pkl"` in a module that is itself loaded over http(s) or from a Pkl package, where relative filesystem resolution is impossible.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- cannotFindStdLibModule
- cannotFindModule
- cannotAnalyzeBecauseSyntaxError
- ioErrorLoadingModule
- invalidGlobPattern
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/1b1bd9c9c2caeb03.
Report an issue: GitHub.