apple/pkl · error · NoSuchChildException

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

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.

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.

Appendix: 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)