{"record":{"id":"1e20f0662d5a1cd2","repo":"apple/pkl","slug":"cannot-resolve-relative-uri-s","errorCode":null,"errorMessage":"Cannot resolve relative URI `%s`.","messagePattern":"Cannot resolve relative URI `(.+?)`\\.","errorType":"console","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/runtime/ModuleResolver.java","lineNumber":70,"sourceCode":"        return ModuleKeys.synthetic(moduleSource.getUri(), moduleSource.getContents());\n      }\n      return resolveCached(moduleSource.getUri(), moduleSource.getContents());\n    }\n    return resolve(moduleSource.getUri());\n  }\n\n  public ModuleKey resolve(URI moduleUri) {\n    return resolve(moduleUri, null);\n  }\n\n  public ModuleKey resolveCached(URI moduleUri, String text) {\n    var underlyingModuleKey = resolve(moduleUri);\n    return ModuleKeys.cached(underlyingModuleKey, text);\n  }\n\n  public ModuleKey resolve(URI moduleUri, @Nullable Node importNode) {\n    if (!moduleUri.isAbsolute()) {\n      throw new VmExceptionBuilder()\n          .withOptionalLocation(importNode)\n          .bug(\"Cannot resolve relative URI `%s`.\", moduleUri)\n          .build();\n    }\n\n    var normalized = moduleUri.normalize();\n    for (var factory : factories) {\n      Optional<ModuleKey> key;\n      try {\n        key = factory.create(normalized);\n      } catch (URISyntaxException e) {\n        throw new VmExceptionBuilder()\n            .withOptionalLocation(importNode)\n            .evalError(\"invalidModuleUri\", moduleUri)\n            .withHint(e.getReason())\n            .build();\n      } catch (ExternalReaderProcessException e) {\n        throw new VmExceptionBuilder()","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/runtime/ModuleResolver.java#L52-L88","documentation":"Pkl's ModuleResolver.resolve() requires an absolute URI before it can look up a module loader. A relative URI reaching this point means an internal resolution step failed to absolutize the module path (e.g. no base URI was available). It is thrown as a bug() — a programmer error, not a user-facing evaluation error.","triggerScenarios":"Calling ModuleResolver.resolve(URI, Node) (directly or via import resolution paths like resolveOutputPaths) with a URI where uri.isAbsolute() is false — e.g. a relative path String never converted against a base URI.","commonSituations":"Embedding/CLI code constructing module URIs manually from CLI args without resolving them against the working directory or a project base; tooling passing paths like 'foo/x.pkl' instead of 'file:///.../foo/x.pkl'.","solutions":["Resolve the relative path against a base URI (e.g. Paths.get(rel).toUri() or base.resolve(rel)) before passing it to resolve().","Check that the VmEvaluator/evaluator context has a base module URI set (e.g. when evaluating a module with no file backing).","If this arises from normal Pkl evaluation, it is an internal bug: report it to the Pkl project with the import chain."],"exampleFix":"// before\nresolver.resolve(URI.create(\"foo/x.pkl\"), node);\n// after\nURI abs = baseDir.toUri().resolve(\"foo/x.pkl\");\nresolver.resolve(abs, node);","handlingStrategy":"validation","validationCode":"if (!moduleUri.isAbsolute()) throw new IllegalArgumentException(\"URI must be absolute: \" + moduleUri);\nresolver.resolve(moduleUri, node);","typeGuard":"static boolean isAbsoluteUri(URI u) { return u != null && u.isAbsolute(); }","tryCatchPattern":null,"preventionTips":["Always build module URIs with Paths.get(...).toUri() or resolve against a base URI.","Never pass raw CLI path strings directly as URIs."],"tags":["uri","module-resolution","internal-error"],"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"}