apple/pkl · error · InvalidGlobPatternException

invalidGlobTooComplex

invalidGlobTooComplex

Error message

invalidGlobTooComplex

What it means

Hierarchical glob expansion enumerates directories recursively and, to protect against pathological patterns and huge trees, counts list-element expansions against a limit (maxListElements). Exceeding it aborts with invalidGlobTooComplex, signaling the glob would traverse too many directory listings rather than a syntax problem.

Solutions

  1. Narrow the glob's base path so expansion starts deeper in the tree (e.g. "src/**/*.pkl" instead of "**/*.pkl")
  2. Replace `**` with fixed intermediate segments where the layout is known
  3. Exclude/generated-code-heavy directories from the glob base (e.g. point at the package dir, not the repo root)

Example fix

// before
glob("**/*.pkl")
// after
glob("src/**/*.pkl")
Defensive patterns

Strategy: try-catch

Validate before calling

// estimate breadth: cap leading ** segments and known huge dirs
const tooBroad = (glob, base) => glob.startsWith('**') && (base === '/' || base === '');

Try / catch

try {
  var files = GlobResolver.expandHierarchicalGlob(...);
} catch (InvalidGlobPatternException e) {
  if (e.getMessage().contains("TooComplex")) {
    // narrow the base path or reduce ** and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Expanding a hierarchical glob (e.g. `**` over a very deep/wide tree, or a pattern matching many nested directories) where the number of directory-list element visits exceeds the configured maxListElements budget in doExpandHierarchicalGlobPart.

Common situations: Running globs against enormous directories (node_modules, build outputs, monorepo roots), overly broad patterns like "**/*" at a filesystem root, or globbing remote/package readers with many elements.

Related errors


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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/util/GlobResolver.java:340

  }

  private static void doExpandHierarchicalGlobPart(
      SecurityManager securityManager,
      ReaderBase reader,
      String expandedGlobSoFar,
      Pattern globPartPattern,
      URI baseUri,
      boolean isGlobStar,
      boolean hasAbsoluteGlob,
      MutableLong listElementCallCount,
      List<ResolvedGlobElement> result)
      throws IOException,
          SecurityManagerException,
          InvalidGlobPatternException,
          ExternalReaderProcessException {

    if (listElementCallCount.getAndIncrement() > maxListElements()) {
      throw new InvalidGlobPatternException(ErrorMessages.create("invalidGlobTooComplex"));
    }
    var elements = reader.listElements(securityManager, baseUri);
    for (var element : sorted(elements)) {
      var elementPath = resolvePath(expandedGlobSoFar, element.getName(), hasAbsoluteGlob);
      if (globPartPattern.matcher(element.getName()).matches()) {
        var name = element.isDirectory() ? element.getName() + "/" : element.getName();
        var elementUri = IoUtils.resolve(reader, baseUri, name);
        result.add(new ResolvedGlobElement(elementPath, elementUri, element.isDirectory()));
      }
      if (element.isDirectory() && isGlobStar) {
        var elementUri = IoUtils.resolve(reader, baseUri, element.getName() + "/");
        var newExpandedGlobPattern =
            resolvePath(expandedGlobSoFar, element.getName(), hasAbsoluteGlob);
        doExpandHierarchicalGlobPart(
            securityManager,
            reader,
            newExpandedGlobPattern,
            globPartPattern,

View on GitHub (pinned to f3efcbfc9b)