apple/pkl · error · VmException

invalidResourceUri

invalidResourceUri

Error message

invalidResourceUri

What it means

If ResourceReader.read(uri) throws URISyntaxException while parsing the resource URI, ResourceManager.doRead() converts it to eval error 'invalidResourceUri' with the URI and the parser's reason as a hint.

Solutions

  1. Percent-encode invalid characters in the resource URI (e.g. spaces as %20).
  2. Validate/normalize the URI string before passing it to read().
  3. Read the error's hint — it states the exact URI parsing problem.

Example fix

// before
read("file:///my docs/data.txt")
// after
read("file:///my%20docs/data.txt")
Defensive patterns

Strategy: validation

Validate before calling

try { new URI(resourceUriString); } catch (URISyntaxException e) { /* fix encoding before read() */ }

Try / catch

catch (VmException e) { if ("invalidResourceUri".equals(e.getCode())) { /* use e hint to explain bad URI */ } }

Prevention

When it happens

Trigger: doRead() called with a syntactically invalid URI (illegal characters, bad percent-encoding) that the reader re-parses strictly, throwing URISyntaxException.

Common situations: read() calls with unescaped spaces or stray '%' in file/http resource paths; interpolated resource URIs where an unexpected value breaks URI syntax.

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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/runtime/ResourceManager.java:83

          .withLocation(readNode)
          .evalError("noResourceReaderRegistered", resourceUri.getScheme())
          .build();
    }
    return reader;
  }

  public Optional<Object> doRead(ResourceReader reader, URI uri, @Nullable Node readNode) {
    Optional<Object> resource;
    try {
      resource = reader.read(uri);
    } catch (IOException e) {
      throw new VmExceptionBuilder()
          .evalError("ioErrorReadingResource", uri)
          .withCause(e)
          .withOptionalLocation(readNode)
          .build();
    } catch (URISyntaxException e) {
      throw new VmExceptionBuilder()
          .evalError("invalidResourceUri", uri)
          .withHint(e.getReason())
          .withOptionalLocation(readNode)
          .build();
    } catch (SecurityManagerException
        | PackageLoadError
        | HttpClientException
        | ExternalReaderProcessException e) {
      throw new VmExceptionBuilder().withCause(e).withOptionalLocation(readNode).build();
    }
    return resource;
  }

  @TruffleBoundary
  public Optional<Object> read(URI resourceUri, @Nullable Node readNode) {
    return resources.computeIfAbsent(
        resourceUri.normalize(),
        (uri) -> {

View on GitHub (pinned to f3efcbfc9b)