apple/pkl · error · PklException
invalidRelativeProjectImport
invalidRelativeProjectImport
Error message
invalidRelativeProjectImport
What it means
Raised when a module imports a path starting with `/` (an absolute path) while the project's directory is not the filesystem root. Package validation forbids absolute-path imports because they cannot be resolved relative to the packaged project.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/project/ProjectPackager.java:451
var imports = getImportsAndReads(pklModulePath);
for (var importContext : imports) {
var importStr = importContext.stringValue();
var sourceSection = importContext.sourceSection();
if (isAbsoluteImport(importStr)) {
continue;
}
URI importUri;
try {
importUri = IoUtils.toUri(importStr);
} catch (URISyntaxException e) {
throw new VmExceptionBuilder()
.evalError("invalidModuleUri", importStr)
.withSourceSection(sourceSection)
.build()
.toPklException(stackFrameTransformer, color);
}
if (importStr.startsWith("/") && !project.getProjectDir().toString().equals("/")) {
throw new VmExceptionBuilder()
.evalError("invalidRelativeProjectImport", importStr)
.withSourceSection(sourceSection)
.build()
.toPklException(stackFrameTransformer, color);
}
var currentPath = pklModulePath.getParent();
assert currentPath != null;
var importPath = importUri.getPath().split("/");
// It's not good enough to just check the normalized path to see whether it exists within the
// root dir.
// It's possible that the import path resolves to a path outside the project dir,
// and then back inside the project dir.
for (var segment : importPath) {
// replace any possibly reserved filename characters with underscore.
currentPath = currentPath.resolve(sanitizePathSegment(segment));
var normalized = currentPath.normalize();
if (!normalized.startsWith(project.getProjectDir())) {
throw new VmExceptionBuilder()View on GitHub (pinned to f3efcbfc9b)
Solutions
- Change the import to a project-relative path (e.g. import "foo/bar.pkl")
- Remove the leading slash from the import string
- If an external file is truly needed, declare it as a dependency instead
Example fix
// before import "/shared/base.pkl" // after import "../shared/base.pkl" // or a project-relative path
Defensive patterns
Strategy: validation
Validate before calling
// reject absolute import paths before packaging
if (importStr.startsWith("/")) throw new IllegalStateException("absolute import not allowed: " + importStr); Try / catch
try { validatePklImportsAndReads(...) } catch (PklException e) { if (e.message.contains("invalidRelativeProjectImport")) showRelativeImportGuidance(e) else throw e } Prevention
- Always write project-relative import paths
- Never copy absolute paths from scratch files into project sources
- Review import statements in code review for leading slashes
When it happens
Trigger: validateImportsAndReads sees an importStr beginning with "/" and project.getProjectDir() != "/" during `pkl project package` validation.
Common situations: Accidentally writing import "/foo/bar.pkl" instead of a relative path; copy-pasted absolute paths from local experiments into project sources.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- invalidModuleUri
- cannotFindModule
- Failed to convert `pkl.base#String` to `java.nio.file.Path`.
- invalidModuleUriMissingSlash
- Is a directory
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/1cb24cb3f3100f45.
Report an issue: GitHub.