apple/pkl · error · PklException

invalidModuleUri

invalidModuleUri

Error message

invalidModuleUri

What it means

Raised as an eval error when an import string inside a module being validated cannot be parsed as a URI (IoUtils.toUri throws URISyntaxException). The error is attached to the import's source section so it points at the offending import statement.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/project/ProjectPackager.java:444

   *
   * <p>Note that these might be glob expressions, so these paths might not actually exist. For
   * example, an import might look like {@code "foo/*.pkl"}, which would resolve as path {@code
   * `/some/dir/foo/*.pkl`}, which is not a real file. This is just a sanity check to ensure that
   * the paths can reasonably resolve to a location within the package directory.
   */
  public void validateImportsAndReads(Project project, Path pklModulePath) {
    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,

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Fix the import string in the .pkl source to be a valid URI (percent-encode or remove illegal characters)
  2. Use forward slashes and no spaces in file names referenced by imports
  3. Quote/escape special characters in the path

Example fix

// before
import "my module/foo.pkl"
// after
import "my_module/foo.pkl"
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate import strings are valid URIs
try { new java.net.URI(importStr); } catch (URISyntaxException e) { /* fix import before packaging */ }

Try / catch

try { validatePklImportsAndReads(project, module, ...) } catch (PklException e) { if (e.message.contains("invalidModuleUri")) reportImportUriError(e) else throw e }

Prevention

When it happens

Trigger: validateImportsAndReads (via validatePklImportsAndReads during packaging) encounters an import string containing characters illegal in a URI, such as spaces or unencoded special characters.

Common situations: Import paths with spaces like import "my module/foo.pkl"; stray backslashes on Windows-style paths; unencoded `#` or `%` in filenames.

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