apple/pkl · error

cannotGlobUri

cannotGlobUri

Error message

cannotGlobUri

What it means

Thrown when a glob is attempted against a URI whose scheme's reader does not support globbing (reader.isGlobbable() is false). Only certain resource types (e.g. local files, module paths) can be globbed; HTTP and most external readers cannot list matches.

Solutions

  1. Glob only local filesystem/module-path URIs; list remote resources explicitly instead.
  2. Enumerate the remote resources another way (an index file, directory listing API) and import each explicitly.
  3. If you own a custom reader, implement glob support (isGlobbable + listing) rather than globbing over it.
  4. Check the scheme in the error message to confirm which reader rejected the glob.

Example fix

// before
read*("https://example.com/configs/*.pkl")
// after
for (name in listOf("a", "b")) {
  read("https://example.com/configs/\(name).pkl")
}
Defensive patterns

Strategy: validation

Validate before calling

const GLOBBABLE_SCHEMES = ['file', 'module', 'projectresource', 'package']
const isGlobbableUri = (u) => GLOBBABLE_SCHEMES.includes(new URL(u).scheme ?? 'file')

Type guard

const canGlob = (uri) => !/^[a-z]+:\/\//.test(uri) || GLOBBABLE_SCHEMES.includes(uri.split('://')[0])

Try / catch

try {
  readGlob(pattern)
} catch (e) {
  if (e.code === 'cannotGlobUri') enumerateResourcesExplicitly(e.data.uri)
  else throw e
}

Prevention

When it happens

Trigger: Calling `read*("https://example.com/*.json")` or globbing any scheme whose registered reader reports isGlobbable() == false; the error carries the URI and its scheme.

Common situations: Trying to glob remote HTTP resources, globbing custom external-reader schemes that only support single reads, assuming URL wildcard expansion works like on a filesystem.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/0a8924ae8264a7b5. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/unary/ReadGlobNode.java:83

  @Specialization
  @TruffleBoundary
  public Object read(String globPattern) {
    var cachedResult = cachedResults.get(globPattern);
    //noinspection ConstantValue
    if (cachedResult != null) return cachedResult;

    // use same check as for globbed imports (see AstBuilder)
    if (globPattern.startsWith("...")) {
      throw exceptionBuilder().evalError("cannotGlobTripleDots").build();
    }
    var globUri = parseUri(globPattern);
    var context = VmContext.get(this);
    try {
      var resolvedUri = IoUtils.resolve(context.getSecurityManager(), currentModule, globUri);
      var reader = context.getResourceManager().getReader(resolvedUri, this);
      if (!reader.isGlobbable()) {
        throw exceptionBuilder().evalError("cannotGlobUri", globUri, globUri.getScheme()).build();
      }
      var resolvedElements =
          GlobResolver.resolveGlob(
              context.getSecurityManager(),
              reader,
              currentModule,
              currentModule.getUri(),
              globPattern);
      var builder = new VmObjectBuilder(resolvedElements.size());
      for (var entry : resolvedElements.entrySet()) {
        builder.addEntry(entry.getKey(), getMemberNode());
      }
      cachedResult = builder.toMapping(resolvedElements);
      cachedResults.put(globPattern, cachedResult);
      return cachedResult;
    } catch (IOException e) {
      throw exceptionBuilder().evalError("ioErrorResolvingGlob", globPattern).withCause(e).build();
    } catch (SecurityManagerException | HttpClientException | URISyntaxException e) {

View on GitHub (pinned to f3efcbfc9b)