apple/pkl · error · VmException

methodNotDefined2

methodNotDefined2

Error message

methodNotDefined2

What it means

ExternalMethod2Node backs Pkl stdlib methods with two arguments. When no specialized node matches the receiver and both argument types, the @Fallback throws "methodNotDefined2" listing the method name and both argument classes. It signals that the two-argument overload does not accept that type combination.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/ExternalMethod2Node.java:34

package org.pkl.core.stdlib;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import org.pkl.core.ast.ExpressionNode;
import org.pkl.core.runtime.VmUtils;

@NodeChild(value = "arg1Node", type = ExpressionNode.class)
@NodeChild(value = "arg2Node", type = ExpressionNode.class)
public abstract class ExternalMethod2Node extends ExternalMethodNode {
  protected abstract ExpressionNode getArg1Node();

  protected abstract ExpressionNode getArg2Node();

  @Fallback
  @TruffleBoundary
  protected Object fallback(@SuppressWarnings("unused") Object receiver, Object arg1, Object arg2) {
    throw exceptionBuilder()
        .evalError(
            "methodNotDefined2",
            getQualifiedMemberName(),
            VmUtils.getClass(arg1),
            VmUtils.getClass(arg2))
        .withProgramValue("Argument 1", arg1)
        .withProgramValue("Argument 2", arg2)
        .build();
  }

  public interface Factory {
    ExternalMethod2Node create(
        ExpressionNode receiverNode, ExpressionNode arg1Node, ExpressionNode arg2Node);
  }
}

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Check both reported argument classes against the method's signature in the stdlib docs.
  2. Insert explicit conversions (.toString(), .toInt(), .toBoolean()) on the offending argument.
  3. Fix argument order if the types look transposed.
  4. Pin/upgrade the Pkl version if the overload set changed between releases.

Example fix

// before
str.replace(find, /* limit */ "all")
// after
str.replace(find, 0) // Int limit, not String
Defensive patterns

Strategy: type-guard

Validate before calling

// Pkl
assert(isString(find) && isString(replacement), "replace args must be Strings")

Type guard

function areStrings2(a, b) = a is String && b is String

Prevention

When it happens

Trigger: Calling a two-argument stdlib method with wrong types in either slot — e.g. Map.getOrNull with a non-key type, String.replace with Int arguments, or swapping the intended argument order.

Common situations: Swapped arguments (value/position); a variable holding the wrong type due to an upstream default; API drift between Pkl versions for the method signature.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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