apple/pkl · error · NoSuchChildException

Leaf node `%s` of type `%s` does not have a child named `%s`

Error message

Leaf node `%s` of type `%s` does not have a child named `%s`.

What it means

LeafConfig wraps a scalar Pkl value (string, int, boolean, etc.). By definition a leaf has no children, so any attempt to read a child property from it unconditionally throws NoSuchChildException naming the leaf's value type and the requested child name. The error exists to convert a structural mistake — treating a scalar as an object — into a clear diagnostic.

Source

Thrown at pkl-config-java/src/main/java/org/pkl/config/java/LeafConfig.java:36

import org.pkl.config.java.mapper.ValueMapper;
import org.pkl.core.PClassInfo;

class LeafConfig extends AbstractConfig {
  private final Object value;

  LeafConfig(String qualifiedName, ValueMapper mapper, Object value) {
    super(qualifiedName, mapper);
    this.value = value;
  }

  @Override
  public Object getRawValue() {
    return value;
  }

  @Override
  protected Object getRawChildValue(String propertyName) {
    throw new NoSuchChildException(
        String.format(
            "Leaf node `%s` of type `%s` does not have a child named `%s`.",
            qualifiedName, PClassInfo.forValue(value).getQualifiedName(), propertyName),
        propertyName);
  }
}

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Call getRawValue() (or the typed value getter) on the node instead of requesting children.
  2. Verify the node's structure against the .pkl source; update access code to match whether it is an object or scalar.
  3. Regenerate typed config classes after schema changes.
  4. Use instanceof/Config subclass checks (CompositeConfig vs LeafConfig) before navigating children.

Example fix

// before
Object child = leafConfig.getChild("name"); // leaf has no children
// after
Object value = leafConfig.getRawValue();
if (value instanceof Map<?,?> map) {
  Object child = map.get("name");
}
Defensive patterns

Strategy: type-guard

Validate before calling

// check node kind before navigating children
if (node instanceof LeafConfig) {
  Object value = ((LeafConfig) node).getRawValue();
  // treat as scalar; do not call getChild
}

Type guard

static boolean isLeaf(Config node) {
  return node instanceof LeafConfig;
}

Try / catch

try {
  return node.getChild(name);
} catch (NoSuchChildException e) {
  if (node instanceof LeafConfig leaf) {
    return leaf.getRawValue(); // caller actually wanted the scalar
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling getChild/property accessors (routed to getRawChildValue) on a config node that wraps a leaf value, e.g. config.get("someScalar").get("field") or string-keyed access on a scalar node.

Common situations: The .pkl schema changed a nested object into a scalar (or vice versa) while the Java access code still expects an object; navigating config generically without checking node kind first; mis-typed generated accessor invoked on the wrong node.

Related errors


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