apple/pkl · error · VmException

cannotInstantiateExternalClass

cannotInstantiateExternalClass

Error message

cannotInstantiateExternalClass

What it means

The external-class counterpart in `VmUtils.checkIsInstantiable`: when the class is not abstract but `isExternal()` (implemented in Java/native code, e.g. stdlib types like Int, List), it cannot be instantiated from Pkl with `new`, so cannotInstantiateExternalClass is thrown.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java:904

    }

    return resolvedNodes;
  }

  public static void checkIsInstantiable(VmClass parentClass, @Nullable Node parentNode) {
    if (parentClass.isInstantiable()) return;

    CompilerDirectives.transferToInterpreter();

    if (parentClass.isAbstract()) {
      throw new VmExceptionBuilder()
          .evalError("cannotInstantiateAbstractClass", parentClass)
          .withOptionalLocation(parentNode)
          .build();
    }

    assert parentClass.isExternal();
    throw new VmExceptionBuilder()
        .evalError("cannotInstantiateExternalClass", parentClass)
        .withOptionalLocation(parentNode)
        .build();
  }

  @TruffleBoundary
  public static Pattern compilePattern(String pattern, Node location) {
    try {
      return Pattern.compile(pattern, Pattern.UNICODE_CHARACTER_CLASS | Pattern.UNICODE_CASE);
    } catch (PatternSyntaxException e) {
      throw new VmExceptionBuilder()
          .withLocation(location)
          .evalError("invalidRegexSyntax", pattern, e.getMessage())
          .build();
    }
  }

  @TruffleBoundary

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Use literals or stdlib constructors instead: `42`, `List(1,2,3)`, `"text"`, `Map(...)`, etc.
  2. Use the corresponding factory function from `pkl.*` modules rather than `new`.
  3. Remove the `new` expression entirely if the value should just be typed, not constructed.
  4. Define your own (non-external) class if you need a custom instance shape.

Example fix

// before
val xs = new List {}
// after
val xs = List()
Defensive patterns

Strategy: validation

Validate before calling

// do not `new` stdlib/external types; use literals and factories
const xs = List(1, 2, 3);

Type guard

function isPklConstructible(cls) { return !cls.isExternal && !cls.isAbstract; }

Try / catch

try { new ExternalCls {} } catch (e) { /* fall back to literal/factory construction */ }

Prevention

When it happens

Trigger: `new Int {}`, `new List {}`, or `new <any external class> {}` — attempting to construct a built-in/external class from Pkl source.

Common situations: Confusing type names with constructors, trying to build stdlib-like values via `new` instead of literals or stdlib factory functions.

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