{"record":{"id":"f860c10b3bf64959","repo":"apple/pkl","slug":"invalidopaquefileuri","errorCode":"invalidOpaqueFileUri","errorMessage":"File URIs must have a path that starts with `/` (e.g. file:/path/to/my_module.pkl).","messagePattern":"File URIs must have a path that starts with `/` \\(e\\.g\\. file:/path/to/my_module\\.pkl\\)\\.","errorType":"error_code","errorClass":"URISyntaxException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/IoUtils.java","lineNumber":893,"sourceCode":"  /** Returns a path string that uses unix-like path separators. */\n  public static String toNormalizedPathString(Path path) {\n    if (isWindows()) {\n      return path.toString().replace(\"\\\\\", \"/\");\n    }\n    return path.toString();\n  }\n\n  private static int getExclamationMarkIndex(String jarUri) {\n    var index = jarUri.indexOf('!');\n    if (index == -1) {\n      throw new IllegalArgumentException(\"Invalid `jar:` URI (missing `!`): \" + jarUri);\n    }\n    return index;\n  }\n\n  public static void validateFileUri(URI uri) throws URISyntaxException {\n    if (!uri.getSchemeSpecificPart().startsWith(\"/\")) {\n      throw new URISyntaxException(uri.toString(), ErrorMessages.create(\"invalidOpaqueFileUri\"));\n    }\n  }\n\n  public static void validateRewriteRule(URI rewrite) {\n    if (!Objects.equals(rewrite.getScheme(), \"http\")\n        && !Objects.equals(rewrite.getScheme(), \"https\")) {\n      throw new IllegalArgumentException(\n          \"Rewrite rule must start with 'http://' or 'https://', but was '%s'\".formatted(rewrite));\n    }\n\n    if (!rewrite.toString().endsWith(\"/\")) {\n      throw new IllegalArgumentException(\n          \"Rewrite rule must end with '/', but was '%s'\".formatted(rewrite));\n    }\n  }\n\n  private static boolean isReservedHeaderName(String headerName) {\n    var normalizedHeader = headerName.toLowerCase(Locale.ROOT);","sourceCodeStart":875,"sourceCodeEnd":911,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/IoUtils.java#L875-L911","documentation":"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.","triggerScenarios":"Calling IoUtils.validateFileUri with URI.create(\"file:my_module.pkl\") or any file URI built without a leading slash in its path.","commonSituations":"Hand-constructing file URIs by string concatenation without encoding an absolute path, or reading a file URI from user config written in opaque form.","solutions":["Build file URIs from absolute paths, e.g. new File(path).toURI() or Paths.get(p).toUri()","Prefix the path with '/' when constructing the URI manually: file:/path/to/my_module.pkl","Resolve the URI against a base directory before validation"],"exampleFix":"// before\nURI uri = URI.create(\"file:my_module.pkl\");\n// after\nURI uri = java.nio.file.Paths.get(\"my_module.pkl\").toAbsolutePath().toUri();","handlingStrategy":"validation","validationCode":"if (uri.getScheme().equals(\"file\") && !uri.getSchemeSpecificPart().startsWith(\"/\")) throw new IllegalArgumentException(\"file URI must have absolute path\");","typeGuard":"function isValidFileUri(u) { return u.getScheme().equals(\"file\") && u.getSchemeSpecificPart().startsWith(\"/\"); }","tryCatchPattern":"try { IoUtils.validateFileUri(uri) } catch (URISyntaxException e) { /* convert via Paths.get(...).toUri() and retry */ }","preventionTips":["Produce file URIs via Path.toUri()/File.toURI(), never by string concatenation","Reject user-supplied file: URIs that lack a leading '/'","Validate early, before the URI is used for resolution"],"tags":["uri","file","validation"],"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"}