{"record":{"id":"e9bacc203a2105c3","repo":"apple/pkl","slug":"invalidresourceuri-e9bacc","errorCode":"invalidResourceUri","errorMessage":"Resource URI `{0}` has invalid syntax.","messagePattern":"Resource URI `(.+?)` has invalid syntax\\.","errorType":"error_code","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/expression/unary/AbstractReadNode.java","lineNumber":46,"sourceCode":"import org.pkl.core.module.ModuleKey;\nimport org.pkl.core.packages.PackageLoadError;\nimport org.pkl.core.runtime.VmContext;\nimport org.pkl.core.util.IoUtils;\n\npublic abstract class AbstractReadNode extends UnaryExpressionNode {\n  protected final ModuleKey currentModule;\n\n  protected AbstractReadNode(SourceSection sourceSection, ModuleKey currentModule) {\n    super(sourceSection);\n    this.currentModule = currentModule;\n  }\n\n  @TruffleBoundary\n  protected final URI parseUri(String resourceUri) {\n    try {\n      return IoUtils.toUri(resourceUri);\n    } catch (URISyntaxException e) {\n      throw exceptionBuilder()\n          .evalError(\"invalidResourceUri\", resourceUri)\n          .withHint(e.getReason())\n          .build();\n    }\n  }\n\n  @TruffleBoundary\n  protected final @Nullable Object doRead(String resourceUri, VmContext context, Node readNode) {\n    var resolvedUri = resolveResource(currentModule, resourceUri);\n    return context.getResourceManager().read(resolvedUri, readNode).orElse(null);\n  }\n\n  private URI resolveResource(ModuleKey moduleKey, String resourceUri) {\n    var parsedUri = parseUri(resourceUri);\n    var context = VmContext.get(this);\n    URI resolvedUri;\n    try {\n      resolvedUri = IoUtils.resolve(context.getSecurityManager(), moduleKey, parsedUri);","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/expression/unary/AbstractReadNode.java#L28-L64","documentation":"Pkl throws this when a resource URI string passed to a `read()` expression cannot be parsed into a valid java.net.URI. The Pkl evaluator catches the URISyntaxException thrown while parsing the resource path and surfaces it as this evaluation error, attaching the parser's reason as a hint.","triggerScenarios":"Calling `read(\"...\")` with a string that is not syntactically a valid URI, e.g. containing illegal characters like spaces, unencoded braces, or a malformed scheme.","commonSituations":"Interpolating file paths with spaces or special characters into a resource URI; concatenating a base URL with a path without encoding; typos like `file:/path with space/data.json`.","solutions":["Percent-encode invalid characters in the resource string before passing it to read() (spaces as %20, etc.).","Check the error hint for the exact character/position reported by the URI parser and fix that spot.","Use a proper URI builder or encode the dynamic portion, e.g. read(\"https://example.com/\" + Uri.encode(path)).","For local files, prefer file URIs with forward slashes and no spaces, or rename the file."],"exampleFix":"// before\nread(\"file:/data dir/config.json\")\n// after\nread(\"file:/data%20dir/config.json\")","handlingStrategy":"validation","validationCode":"// Pkl / host-side pre-check that a resource string is URI-safe\nfun isUriSafe(s: String): Boolean =\n  s.isNotBlank() && !s.any { it.isWhitespace() || it in \"{}|\\\\^`<>\\\"\" } && Regex(\"^[a-zA-Z][a-zA-Z0-9+.-]*:\").containsMatchIn(s)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always percent-encode dynamic path segments before interpolating into resource URIs.","Avoid raw OS paths with spaces/backslashes; build proper file:// URIs.","Validate interpolated values (they may contain user/environment data) before read()."],"tags":["uri","resource","syntax","pkl"],"backgroundTag":"invalid-url-format","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}