apple/pkl · error · URISyntaxException

invalidModuleUriMissingSlash

invalidModuleUriMissingSlash

Error message

invalidModuleUriMissingSlash

What it means

URISyntaxException thrown by the PackageUri constructor when the given URI is opaque — it lacks the hierarchical `/` separator after the scheme (e.g. `package:foo/bar` instead of `package:/foo/bar`). A package URI must be hierarchical with scheme `package` or `projectpackage`.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/packages/PackageUri.java:46

  private final Version version;
  private final String pathWithoutVersion;
  private @Nullable Checksums checksums;

  public static PackageUri create(String baseUri) {
    try {
      return new PackageUri(baseUri);
    } catch (URISyntaxException e) {
      throw new IllegalArgumentException(e);
    }
  }

  public PackageUri(String baseUri) throws URISyntaxException {
    this(new URI(baseUri));
  }

  public PackageUri(URI uri) throws URISyntaxException {
    if (uri.isOpaque()) {
      throw new URISyntaxException(
          uri.toString(), ErrorMessages.create("invalidModuleUriMissingSlash", uri, "package"));
    }
    var scheme = uri.getScheme();
    if (scheme == null || !(scheme.equals("package") || scheme.equals("projectpackage"))) {
      throw new URISyntaxException(
          uri.toString(), ErrorMessages.create("invalidSchemeInPackageUri", scheme));
    }
    var authority = uri.getAuthority();
    if (authority == null || authority.isEmpty()) {
      throw new URISyntaxException(
          uri.toString(), ErrorMessages.create("missingAuthorityInPackageUri", uri));
    }
    var path = uri.getPath();
    if (path == null || path.isEmpty()) {
      throw new URISyntaxException(
          uri.toString(), ErrorMessages.create("missingPathInPackageUri", uri));
    }
    // reject `..` segments, percent-encoded or not

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Insert the hierarchical separator: `package:/...` instead of `package:...`
  2. Validate the URI string before constructing, e.g. check it starts with `package:/` or `projectpackage:/`
  3. If the value comes from config, quote/copy the exact package URI published by the package author
  4. Use URI.create and inspect uri.isOpaque() yourself for a friendlier pre-check

Example fix

// before
new PackageUri("package:example.com/my-pkg@1.0.0");
// after
new PackageUri("package:/example.com/my-pkg@1.0.0");
Defensive patterns

Strategy: validation

Validate before calling

// validate before constructing PackageUri
static boolean isValidPackageUri(String s) {
  return s.startsWith("package:/") || s.startsWith("projectpackage:/");
}

Type guard

PackageUri tryParsePackageUri(String s) {
  if (s == null || !s.matches("(package|projectpackage):/.*")) return null;
  try { return new PackageUri(s); } catch (URISyntaxException e) { return null; }
}

Try / catch

try {
  var packageUri = new PackageUri(uriString);
} catch (URISyntaxException e) {
  if (e.getReason().contains("missing slash") || e.getReason().contains("opaque")) {
    uriString = uriString.replaceFirst("^(package|projectpackage):", "$1:/");
  }
}

Prevention

When it happens

Trigger: Constructing `new PackageUri(String)` or `new PackageUri(URI)` with an opaque URI such as `package:my.pkg` (no slash after the colon), or a URI whose scheme is not `package`/`projectpackage` (separate invalidSchemeInPackageUri error).

Common situations: Hand-writing a package URI in a PklProject dependency without the leading slash; programmatic URI building that concatenates scheme and path without `:/`; copying a URN-style identifier into a package URI field.

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