apple/pkl · error · VmException

expectedSingleElementCollection

expectedSingleElementCollection

Error message

expectedSingleElementCollection

What it means

Thrown by VmCollection.checkLengthOne() when a Pkl collection does not contain exactly one element. Pkl throws it where code expects a single-element collection and calls an operation (like converting to a single value) that only makes sense with exactly one element. The collection itself is attached as program value 'Collection'.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/runtime/VmCollection.java:65

  public abstract Builder<? extends VmCollection> builder();

  public final void checkNonEmpty() {
    if (isEmpty()) {
      CompilerDirectives.transferToInterpreter();
      throw new VmExceptionBuilder()
          .evalError("expectedNonEmptyCollection")
          .withProgramValue("Collection", this)
          .build();
    }
  }

  @SuppressWarnings("BooleanMethodIsAlwaysInverted")
  public abstract boolean isLengthOne();

  public final void checkLengthOne() {
    if (!isLengthOne()) {
      CompilerDirectives.transferToInterpreter();
      throw new VmExceptionBuilder()
          .evalError("expectedSingleElementCollection")
          .withProgramValue("Collection", this)
          .build();
    }
  }

  protected static void checkPositive(long n) {
    VmUtils.checkPositive(n);
  }

  @TruffleBoundary
  public final boolean startsWith(VmCollection other) {
    if (getLength() < other.getLength()) return false;

    var iter = iterator();
    var otherIter = other.iterator();

    //noinspection WhileLoopReplaceableByForEach

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Inspect the collection reported in the 'Collection' program value and determine why it has != 1 elements
  2. If multiple values are possible, index the collection explicitly (e.g. lst[0]) or pick the desired element
  3. If zero elements are possible, add a null/empty check before the operation
  4. Fix the upstream data or glob pattern so it yields exactly one element

Example fix

// before
value = someListing.first
// after
value = if (someListing.isEmpty) throw("expected exactly one element") else someListing.first
Defensive patterns

Strategy: validation

Validate before calling

if (coll.length == 1) { /* proceed */ } else { throw "expected exactly one element, got \(coll.length)" }

Type guard

function isSingleton<T>(c: Iterable<T>): boolean { return c.size === 1 }

Prevention

When it happens

Trigger: Calling checkLengthOne() on a collection with 0 or 2+ elements; e.g. evaluating an operation that requires a singleton collection such as flattening contexts or implicit element extraction from a collection.

Common situations: Expecting a listing to match exactly one file/glob result but getting zero or multiple matches; passing a List/Set/Mapping with several elements where a single element is required.

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