apple/pkl · error · VmException

invalidModuleUri

invalidModuleUri

Error message

invalidModuleUri

What it means

When resolving a module URI, Pkl iterates registered ModuleKey factories; if a factory throws URISyntaxException while parsing the normalized URI, the resolver converts it into an eval error 'invalidModuleUri' with the raw URI and the parser's reason as a hint.

Solutions

  1. Fix the URI string: percent-encode spaces and special characters (%20) and fix malformed escape sequences.
  2. In Java code, validate with new URI(str) or use Paths.get(...).toUri() to build a well-formed URI before calling resolve().
  3. Check the hint attached to the error — it names the exact parsing reason.

Example fix

// before
URI.create("file:///my dir/pkg.pkl");
// after
URI.create("file:///my%20dir/pkg.pkl");
Defensive patterns

Strategy: validation

Validate before calling

try { new URI(moduleUriString); } catch (URISyntaxException e) { /* fix before calling resolve() */ }

Try / catch

catch (VmException e) { if ("invalidModuleUri".equals(e.getCode())) { /* surface hint to user */ } }

Prevention

When it happens

Trigger: Passing a syntactically malformed URI to resolve() (or importing one), e.g. 'file:///a b.pkl' with illegal characters or '%zz' bad percent-encoding, causing factory.create(normalized) to throw URISyntaxException.

Common situations: Imports with unescaped spaces or special characters in paths; programmatically built URIs from unvalidated strings; bad percent-encoding in custom-scheme module paths.

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/7dcd8d2f7abfdfd9. Report an issue: GitHub.

Appendix: source

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

    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()
            .withOptionalLocation(importNode)
            .evalError("externalReaderFailure")
            .withCause(e)
            .build();
      } catch (IOException e) {
        throw new VmExceptionBuilder()
            .withOptionalLocation(importNode)
            .evalError("ioErrorLoadingModule")
            .withCause(e)
            .build();
      }
      if (key.isPresent()) return key.get();

View on GitHub (pinned to f3efcbfc9b)