apple/pkl · error · VmException

yamlParseErrorTooManyAliases

yamlParseErrorTooManyAliases

Error message

yamlParseErrorTooManyAliases

What it means

`yaml.parse` throws `yamlParseErrorTooManyAliases` when the SnakeYAML engine rejects the document because the number of aliases for non-scalar nodes exceeds the configured limit (`maxCollectionAliases`, default 50). This limit exists to prevent YAML 'billion laughs'/alias-expansion denial-of-service attacks. The configured max is included as an error parameter.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/yaml/ParserNodes.java:77

    @TruffleBoundary
    protected Object eval(
        VmTyped self, VmTyped resource, @Cached("create()") IndirectCallNode callNode) {
      var text = (String) VmUtils.readMember(resource, Identifier.TEXT, callNode);
      var uri = (String) VmUtils.readMember(resource, Identifier.URI, callNode);
      return doParse(self, text, uri);
    }

    private Object doParse(VmTyped self, String text, String uri) {
      var converter = PklConverter.fromParser(self);
      var load = createLoad(self, text, uri, converter);

      try {
        var document = load.loadFromString(text);
        return converter.convert(document, List.of());
      } catch (YamlEngineException e) {
        if (e.getMessage()
            .startsWith("Number of aliases for non-scalar nodes exceeds the specified")) {
          throw exceptionBuilder()
              .evalError("yamlParseErrorTooManyAliases", getMaxCollectionAliases(self))
              .build();
        }
        throw exceptionBuilder().evalError("yamlParseError").withHint(e.getMessage()).build();
      }
    }
  }

  public abstract static class parseAll extends ExternalMethod1Node {
    @Specialization
    @TruffleBoundary
    protected VmList eval(VmTyped self, String text) {
      var uri = "input_string";
      return doParseAll(self, text, uri);
    }

    @Specialization
    @TruffleBoundary

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Raise the limit by setting `maxCollectionAliases` on the yaml receiver before parsing
  2. De-duplicate the document: replace repeated aliased blocks with literal values (e.g. via yq or a preprocessor)
  3. Reduce anchor/alias usage in the source YAML, inlining the referenced nodes
  4. If the aliases are only scalar anchors, keep them — the limit only counts non-scalar (map/list) aliases

Example fix

// before
yaml.maxCollectionAliases = 50
result = yaml.parse(text)
// after
yaml.maxCollectionAliases = 1000
result = yaml.parse(text)
Defensive patterns

Strategy: validation

Validate before calling

// rough pre-check: count anchor definitions and alias uses
aliasCount = text.split("*").length - 1
assert(aliasCount <= yaml.maxCollectionAliases)

Try / catch

try {
  doc = yaml.parse(text)
} catch (e) {
  if (e.message.contains("aliases")) {
    yaml.maxCollectionAliases = 10000
    doc = yaml.parse(text)
  } else throw e
}

Prevention

When it happens

Trigger: Calling `yaml.parse(text)` on a YAML document containing more alias references to non-scalar (collection) anchors than the limit set via `maxCollectionAliases` on the receiver; raised in ParserNodes.doParse when the YamlEngineException message starts with 'Number of aliases for non-scalar nodes exceeds the specified'.

Common situations: Parsing machine-generated or deeply self-referential YAML (e.g. Kubernetes manifests, serialized object dumps) with many repeated anchors/aliases; documents exported from YAML libraries that aggressively share structures.

Related errors


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