apple/pkl · error · VmException

Cannot resolve relative URI

Error message

Cannot resolve relative URI `%s`.

What it means

Pkl's ModuleResolver.resolve() requires an absolute URI before it can look up a module loader. A relative URI reaching this point means an internal resolution step failed to absolutize the module path (e.g. no base URI was available). It is thrown as a bug() — a programmer error, not a user-facing evaluation error.

Solutions

  1. Resolve the relative path against a base URI (e.g. Paths.get(rel).toUri() or base.resolve(rel)) before passing it to resolve().
  2. Check that the VmEvaluator/evaluator context has a base module URI set (e.g. when evaluating a module with no file backing).
  3. If this arises from normal Pkl evaluation, it is an internal bug: report it to the Pkl project with the import chain.

Example fix

// before
resolver.resolve(URI.create("foo/x.pkl"), node);
// after
URI abs = baseDir.toUri().resolve("foo/x.pkl");
resolver.resolve(abs, node);
Defensive patterns

Strategy: validation

Validate before calling

if (!moduleUri.isAbsolute()) throw new IllegalArgumentException("URI must be absolute: " + moduleUri);
resolver.resolve(moduleUri, node);

Type guard

static boolean isAbsoluteUri(URI u) { return u != null && u.isAbsolute(); }

Prevention

When it happens

Trigger: Calling ModuleResolver.resolve(URI, Node) (directly or via import resolution paths like resolveOutputPaths) with a URI where uri.isAbsolute() is false — e.g. a relative path String never converted against a base URI.

Common situations: Embedding/CLI code constructing module URIs manually from CLI args without resolving them against the working directory or a project base; tooling passing paths like 'foo/x.pkl' instead of 'file:///.../foo/x.pkl'.

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


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/1e20f0662d5a1cd2. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/runtime/ModuleResolver.java:70

        return ModuleKeys.synthetic(moduleSource.getUri(), moduleSource.getContents());
      }
      return resolveCached(moduleSource.getUri(), moduleSource.getContents());
    }
    return resolve(moduleSource.getUri());
  }

  public ModuleKey resolve(URI moduleUri) {
    return resolve(moduleUri, null);
  }

  public ModuleKey resolveCached(URI moduleUri, String text) {
    var underlyingModuleKey = resolve(moduleUri);
    return ModuleKeys.cached(underlyingModuleKey, text);
  }

  public ModuleKey resolve(URI moduleUri, @Nullable Node importNode) {
    if (!moduleUri.isAbsolute()) {
      throw new VmExceptionBuilder()
          .withOptionalLocation(importNode)
          .bug("Cannot resolve relative URI `%s`.", moduleUri)
          .build();
    }

    var normalized = moduleUri.normalize();
    for (var factory : factories) {
      Optional<ModuleKey> key;
      try {
        key = factory.create(normalized);
      } catch (URISyntaxException e) {
        throw new VmExceptionBuilder()
            .withOptionalLocation(importNode)
            .evalError("invalidModuleUri", moduleUri)
            .withHint(e.getReason())
            .build();
      } catch (ExternalReaderProcessException e) {
        throw new VmExceptionBuilder()

View on GitHub (pinned to f3efcbfc9b)