apple/pkl · error · URISyntaxException

invalidOpaqueFileUri

invalidOpaqueFileUri

Error message

File URIs must have a path that starts with `/` (e.g. file:/path/to/my_module.pkl).

What it means

validateFileUri rejects file: URIs whose scheme-specific part does not start with '/' (opaque file URIs like file:foo.pkl). Pkl requires hierarchical file URIs with an absolute path so they can be converted to filesystem paths deterministically.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/util/IoUtils.java:893

  /** Returns a path string that uses unix-like path separators. */
  public static String toNormalizedPathString(Path path) {
    if (isWindows()) {
      return path.toString().replace("\\", "/");
    }
    return path.toString();
  }

  private static int getExclamationMarkIndex(String jarUri) {
    var index = jarUri.indexOf('!');
    if (index == -1) {
      throw new IllegalArgumentException("Invalid `jar:` URI (missing `!`): " + jarUri);
    }
    return index;
  }

  public static void validateFileUri(URI uri) throws URISyntaxException {
    if (!uri.getSchemeSpecificPart().startsWith("/")) {
      throw new URISyntaxException(uri.toString(), ErrorMessages.create("invalidOpaqueFileUri"));
    }
  }

  public static void validateRewriteRule(URI rewrite) {
    if (!Objects.equals(rewrite.getScheme(), "http")
        && !Objects.equals(rewrite.getScheme(), "https")) {
      throw new IllegalArgumentException(
          "Rewrite rule must start with 'http://' or 'https://', but was '%s'".formatted(rewrite));
    }

    if (!rewrite.toString().endsWith("/")) {
      throw new IllegalArgumentException(
          "Rewrite rule must end with '/', but was '%s'".formatted(rewrite));
    }
  }

  private static boolean isReservedHeaderName(String headerName) {
    var normalizedHeader = headerName.toLowerCase(Locale.ROOT);

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Build file URIs from absolute paths, e.g. new File(path).toURI() or Paths.get(p).toUri()
  2. Prefix the path with '/' when constructing the URI manually: file:/path/to/my_module.pkl
  3. Resolve the URI against a base directory before validation

Example fix

// before
URI uri = URI.create("file:my_module.pkl");
// after
URI uri = java.nio.file.Paths.get("my_module.pkl").toAbsolutePath().toUri();
Defensive patterns

Strategy: validation

Validate before calling

if (uri.getScheme().equals("file") && !uri.getSchemeSpecificPart().startsWith("/")) throw new IllegalArgumentException("file URI must have absolute path");

Type guard

function isValidFileUri(u) { return u.getScheme().equals("file") && u.getSchemeSpecificPart().startsWith("/"); }

Try / catch

try { IoUtils.validateFileUri(uri) } catch (URISyntaxException e) { /* convert via Paths.get(...).toUri() and retry */ }

Prevention

When it happens

Trigger: Calling IoUtils.validateFileUri with URI.create("file:my_module.pkl") or any file URI built without a leading slash in its path.

Common situations: Hand-constructing file URIs by string concatenation without encoding an absolute path, or reading a file URI from user config written in opaque form.

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