{"record":{"id":"c5bb9ebb2a8a329c","repo":"apple/pkl","slug":"expected-absolute-uri-but-got","errorCode":null,"errorMessage":"Expected absolute URI, but got: ","messagePattern":"Expected absolute URI, but got: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/IoUtils.java","lineNumber":298,"sourceCode":"    var lastDot = path.lastIndexOf('.');\n    return lastDot == -1 || lastDot < lastSep\n        ? path.substring(lastSep + 1)\n        : path.substring(lastSep + 1, lastDot);\n  }\n\n  public static String takeLastSegment(String name, char separator) {\n    var lastSep = name.lastIndexOf(separator);\n    return name.substring(lastSep + 1);\n  }\n\n  public static String dropLastSegment(String name, char separator) {\n    var lastSep = name.lastIndexOf(separator);\n    return lastSep == -1 ? name : name.substring(0, lastSep);\n  }\n\n  public static @Nullable Path toPath(URI uri) {\n    if (!uri.isAbsolute()) {\n      throw new IllegalArgumentException(\"Expected absolute URI, but got: \" + uri);\n    }\n\n    try {\n      return Path.of(uri);\n    } catch (IllegalArgumentException | FileSystemNotFoundException e) {\n      return null;\n    }\n  }\n\n  private static String doInferModuleName(URI moduleUri) {\n    var path = moduleUri.getPath();\n    if (path == null) { // equivalent to `URI.isOpaque()`\n      // convention: take last segment of dot-separated name\n      // after stripping any colon-separated version number\n      return takeLastSegment(dropLastSegment(moduleUri.getSchemeSpecificPart(), ':'), '.');\n    }\n    return getNameWithoutExtension(path);\n  }","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/IoUtils.java#L280-L316","documentation":"IoUtils.toPath(URI) converts an absolute URI into a java.nio.file.Path. The library throws this IllegalArgumentException when the URI is relative (has no scheme), because a relative URI cannot denote a filesystem location.","triggerScenarios":"Calling IoUtils.toPath() with a URI whose isAbsolute() is false, e.g. URI created from 'foo/bar.pkl' or created via URI.create(\"relative/path\") instead of a file: or other absolute scheme.","commonSituations":"Resolving imports against a relative path, forgetting to call baseUri.resolve(relative) before conversion, reading a URI from config where the scheme part was omitted.","solutions":["Ensure the URI has a scheme before calling toPath, e.g. resolve it against a base: base.resolve(relativeUri)","Check uri.isAbsolute() yourself and handle the relative case explicitly","If the input should be a filesystem path, convert via Paths.get(String) instead of wrapping in a URI"],"exampleFix":"// before\nPath p = IoUtils.toPath(URI.create(\"modules/foo.pkl\"));\n// after\nURI u = URI.create(\"modules/foo.pkl\");\nPath p = u.isAbsolute() ? IoUtils.toPath(u) : IoUtils.toPath(baseDir.toUri().resolve(u));","handlingStrategy":"validation","validationCode":"if (!uri.isAbsolute()) { uri = baseUri.resolve(uri); }\nPath p = IoUtils.toPath(uri);","typeGuard":"function isAbsoluteUri(u) { return u != null && u.getScheme() != null; }","tryCatchPattern":"try { return IoUtils.toPath(uri); } catch (IllegalArgumentException e) { /* handle relative URI */ return null; }","preventionTips":["Always resolve relative URIs against a known base before conversion","Build URIs with toUri() from Path/File objects instead of parsing strings","Assert uri.isAbsolute() in unit tests for URI-producing code"],"tags":["uri","path","argument-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-17T15:17:12.973Z"}