apple/pkl · error · InvalidUserDataException

Failed to parse Pkl module URI: ${s}

Error message

Failed to parse Pkl module URI: ${s}

What it means

For String notations that look URI-like, parseModuleNotation converts the string with IoUtils.toUri(); a URISyntaxException is wrapped in InvalidUserDataException "Failed to parse Pkl module URI: <s>". It lets malformed URI strings (bad scheme, illegal characters) fail with a clear message rather than obscure CLI errors later.

Source

Thrown at pkl-gradle/src/main/java/org/pkl/gradle/utils/PluginUtils.java:97

    } else if (notation instanceof Path path) {
      try {
        return path.toFile();
      } catch (UnsupportedOperationException e) {
        throw new InvalidUserDataException("Failed to parse Pkl module file path: " + notation, e);
      }
    } else if (notation instanceof URL url) {
      try {
        return parseModuleNotation(url.toURI());
      } catch (URISyntaxException e) {
        throw new InvalidUserDataException("Failed to parse Pkl module URI: " + notation, e);
      }
    } else if (notation instanceof CharSequence) {
      var s = notation.toString();
      if (IoUtils.isUriLike(s)) {
        try {
          return parseModuleNotation(IoUtils.toUri(s));
        } catch (URISyntaxException e) {
          throw new InvalidUserDataException("Failed to parse Pkl module URI: " + s, e);
        }
      } else {
        try {
          return Paths.get(s).toFile();
        } catch (InvalidPathException | UnsupportedOperationException e) {
          throw new InvalidUserDataException("Failed to parse Pkl module file path: " + s, e);
        }
      }
    } else if (notation instanceof FileSystemLocation location) {
      return location.getAsFile();
    } else {
      throw new InvalidUserDataException(
          "Unsupported value of type "
              + notation.getClass()
              + " used as a module path: "
              + notation);
    }
  }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Fix the URI string to a valid RFC 3986 form (correct scheme://host/path, percent-encode spaces and reserved chars).
  2. If it is a local path, drop the URI-like prefix or pass it as a plain path so it takes the Paths.get branch.
  3. Build the URI via URI.create/Paths.toUri() to catch encoding issues at the source.
  4. Read the wrapped URISyntaxException cause for the exact error index and offending character.

Example fix

// before
uri = "file://my dir/mod.pkl" // URISyntaxException (space)
// after
uri = "file:///my%20dir/mod.pkl"
Defensive patterns

Strategy: validation

Validate before calling

fun requireValidModuleUri(s: String) { if (s.contains("://") || s.contains(":")) { try { URI(s) } catch (e: URISyntaxException) { throw InvalidUserDataException("Malformed module URI '$s': ${e.reason} at ${e.index}", e) } } }

Type guard

fun isUriLikeAndValid(s: String): Boolean = !s.contains("://") || try { URI(s); true } catch (e: URISyntaxException) { false }

Try / catch

try { parseModuleNotation(uriString) } catch (InvalidUserDataException e) { if (e.cause is URISyntaxException) logger.error("Malformed URI '$uriString': check scheme and encoding"); throw e }

Prevention

When it happens

Trigger: Passing a module string containing "://" or otherwise URI-like but syntactically invalid (e.g. "pkl://a b/mod.pkl", "https:/missing-host", unescaped spaces or brackets) to pkl Gradle module configuration.

Common situations: Typos in remote module URIs (single slash after scheme); interpolating unencoded paths with spaces into https/file URIs; copying URIs with curly quotes or trailing characters from docs; env-specific values injected unescaped.

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