apple/pkl · error · VmException

cannotInferParent

cannotInferParent

Error message

Cannot tell which parent to amend.

What it means

Pkl throws `cannotInferParent` when an amending expression uses the implicit-parent (`new`/`...` with inferred receiver) form but the parent cannot be determined. In AbstractInferParentNode.getDefaultValue, if the type to amend is still a type variable at evaluation time, there is no concrete parent to amend.

Solutions

  1. Make the parent explicit: write `obj { ... }` or `new ConcreteType { ... }` instead of relying on inference.
  2. Move the amendment out of the generic context to where the concrete type is known.
  3. Pass the concrete type as a parameter or specialize the helper per type.

Example fix

// before
function amendIt<T>(x: T): T = x { ... } // cannot infer parent
// after
function amendIt(x: Server): Server = x {
  port = 8080
}
Defensive patterns

Strategy: validation

Validate before calling

// Pkl: avoid inferred parents in generic contexts
function amendIt(x: Server): Server = x { ... } // concrete type, OK

Prevention

When it happens

Trigger: Using `...` (amend without explicit receiver) or a `new` with inferred type inside a generic/type-parameterized context where the type resolves to a TypeVariableNode (e.g. inside a generic function or type-aliased helper).

Common situations: Writing amendment shorthand inside generic utility functions in pkl modules; extending code that relied on concrete types with generics so the implicit parent inference breaks.

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/c63ef2515bbfd131. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/member/AbstractInferParentNode.java:56

  protected Object getDefaultValue(
      VirtualFrame frame,
      @Nullable TypeNode typeNode,
      SourceSection headerSection,
      String qualifiedName) {
    if (typeNode == null || typeNode instanceof UnknownTypeNode) {
      return VmDynamic.empty();
    }

    var defaultValue = typeNode.createDefaultValue(frame, language, headerSection, qualifiedName);
    if (defaultValue != null) {
      return defaultValue;
    }

    CompilerDirectives.transferToInterpreter();

    if (typeNode instanceof TypeVariableNode) {
      throw exceptionBuilder().evalError("cannotInferParent").build();
    }

    // try to produce a more specific error message than "cannotInstantiateType"
    var clazz = typeNode.getVmClass();
    if (clazz != null) {
      VmUtils.checkIsInstantiable(clazz, typeNode);
    }

    throw exceptionBuilder()
        .evalError("cannotInstantiateType", typeNode.getSourceSection().getCharacters())
        .build();
  }
}

View on GitHub (pinned to f3efcbfc9b)