{"record":{"id":"15b7424631c2ef38","repo":"apple/pkl","slug":"failed-to-parse-pkl-module-file-path-notation","errorCode":null,"errorMessage":"Failed to parse Pkl module file path: ${notation}","messagePattern":"Failed to parse Pkl module file path: (.+?)","errorType":"validation","errorClass":"InvalidUserDataException","httpStatus":null,"severity":"error","filePath":"pkl-gradle/src/main/java/org/pkl/gradle/utils/PluginUtils.java","lineNumber":83,"sourceCode":"   * method returns a {@link File} corresponding to the file path in the URI. Otherwise, a {@link\n   * URI} instance is returned.\n   *\n   * @throws InvalidUserDataException In case the input is none of the types described above, or\n   *     when the underlying value cannot be parsed correctly.\n   */\n  public static Object parseModuleNotation(Object notation) {\n    if (notation instanceof URI uri) {\n      if (\"file\".equals(uri.getScheme())) {\n        return new File(uri.getPath());\n      }\n      return uri;\n    } else if (notation instanceof File) {\n      return notation;\n    } else if (notation instanceof Path path) {\n      try {\n        return path.toFile();\n      } catch (UnsupportedOperationException e) {\n        throw new InvalidUserDataException(\"Failed to parse Pkl module file path: \" + notation, e);\n      }\n    } else if (notation instanceof URL url) {\n      try {\n        return parseModuleNotation(url.toURI());\n      } catch (URISyntaxException e) {\n        throw new InvalidUserDataException(\"Failed to parse Pkl module URI: \" + notation, e);\n      }\n    } else if (notation instanceof CharSequence) {\n      var s = notation.toString();\n      if (IoUtils.isUriLike(s)) {\n        try {\n          return parseModuleNotation(IoUtils.toUri(s));\n        } catch (URISyntaxException e) {\n          throw new InvalidUserDataException(\"Failed to parse Pkl module URI: \" + s, e);\n        }\n      } else {\n        try {\n          return Paths.get(s).toFile();","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-gradle/src/main/java/org/pkl/gradle/utils/PluginUtils.java#L65-L101","documentation":"PluginUtils.parseModuleNotation converts Gradle dependency notations (String, File, Path, URL, URI) into a java.io.File for Pkl module sources. When the notation is a java.nio.Path whose toFile() fails with UnsupportedOperationException (e.g. a non-default filesystem provider), it throws InvalidUserDataException with the notation embedded. The cause chain preserves the original exception.","triggerScenarios":"Passing a Path created from a custom/non-default FileSystem (e.g. zipfs or an in-memory filesystem) as a module notation to the pkl Gradle configuration; Path.toFile() throwing UnsupportedOperationException.","commonSituations":"Programmatically building module lists from a zip filesystem (FileSystems.newFileSystem on a jar/zip); test code using Jimfs/MemoryFS and passing those Paths to the plugin; copying paths between filesystems.","solutions":["Convert to a real filesystem path first: copy the file to the default filesystem and pass its path.","Pass a java.io.File or an absolute String path on the default filesystem instead of a custom-FS Path.","Use a URI notation for remote resources rather than a zipfs Path.","Inspect the cause to confirm it is UnsupportedOperationException from toFile()."],"exampleFix":"// before\nFiles.newFileSystem(zip).getPath(\"/mod.pkl\") // passed as notation -> throws\n// after\nFile extracted = File.createTempFile(\"mod\", \".pkl\");\nFiles.copy(zipPath, extracted.toPath(), StandardCopyOption.REPLACE_EXISTING);\n// pass `extracted` as the notation","handlingStrategy":"type-guard","validationCode":"if (notation is Path && notation.fileSystem != FileSystems.getDefault()) {\n  throw InvalidUserDataException(\"Path is on a non-default filesystem: $notation\")\n}","typeGuard":"fun toLocalFile(p: Path): File? = if (p.fileSystem == FileSystems.getDefault()) p.toFile() else null","tryCatchPattern":"try { file = PluginUtils.parseModuleNotation(notation) } catch (InvalidUserDataException e) { logger.error(\"Module notation ${notation} must be on the default filesystem; copy it out first\"); throw e }","preventionTips":["Never pass Paths from zipfs/Jimfs/custom FileSystems into Gradle notations","Copy files to the default filesystem before referencing them","Prefer File or absolute String path notations for local modules","Use URI notation for remote modules instead of virtual-fs paths"],"tags":["gradle","pkl","path","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}