apple/pkl · error
cannotHaveRelativeImport
cannotHaveRelativeImport
Error message
cannotHaveRelativeImport ${moduleUri} What it means
After resolution, if the resulting module URI is not absolute, the builder rejects the import: every loaded module must resolve to an absolute URI. A relative string that could not be resolved against the importing module's URI triggers this.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:3280
} catch (SecurityManagerException | PackageLoadError e) {
throw exceptionBuilder().withSourceSection(createSourceSection(ctx)).withCause(e).build();
} catch (VmException e) {
throw exceptionBuilder()
.evalError(e.getMessage(), e.getMessageArguments())
.withCause(e.getCause())
.withHintBuilder(e.getHintBuilder())
.withSourceSection(createSourceSection(ctx))
.build();
} catch (ExternalReaderProcessException e) {
throw exceptionBuilder()
.evalError("externalReaderFailure")
.withCause(e.getCause())
.withSourceSection(createSourceSection(ctx))
.build();
}
if (!resolvedUri.isAbsolute()) {
throw exceptionBuilder()
.evalError("cannotHaveRelativeImport", moduleKey.getUri())
.withSourceSection(createSourceSection(ctx))
.build();
}
return resolvedUri;
}
private ConstLevel getConstLevel(int modifiers) {
if (VmModifier.isConst(modifiers)) return ConstLevel.ALL;
return symbolTable.getCurrentScope().getConstLevel();
}
private VmException missingLocalPropertyValue(TypeAnnotation typeAnn) {
var stop = typeAnn.span().stopIndex();
return exceptionBuilder()
.evalError("missingLocalPropertyValue")
.withSourceSection(source.createSection(stop + 1, 0))
.build();View on GitHub (pinned to f3efcbfc9b)
Solutions
- Load the module from a concrete file/project so relative imports can resolve
- Rewrite the import as an absolute URI (file:///... or package://...)
- Pass an explicit base/module URI when using the embedding APIs
Example fix
// before (no base for relative import) import "config/base.pkl" // after import "file:///opt/pkl/config/base.pkl"
Defensive patterns
Strategy: validation
Validate before calling
function resolvesAbsolute(base, ref) {
try { return new URL(ref, base).href } catch { return null }
} Prevention
- Load modules from real files/projects so relative imports have a base
- When embedding Pkl, always supply a concrete module/base URI
- Use absolute URIs for imports in string-sourced modules
When it happens
Trigger: An `import` with a relative path used in a context with no base URI to resolve against (e.g. module loaded from a string/stdin), leaving `resolvedUri` relative.
Common situations: Evaluating modules from stdin or in-memory where relative imports have no filesystem anchor; programmatic use of `pkl` APIs with a module source lacking a base.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/fe8d5e6ae317bb80.
Report an issue: GitHub.