apple/pkl · error · VmException

cannotFlattenCollectionWithNonCollectionElement

cannotFlattenCollectionWithNonCollectionElement

Error message

cannotFlattenCollectionWithNonCollectionElement

What it means

Thrown by VmCollection.flatten() when flattening encounters an element that is itself not a collection/listing. Flattening requires every element to be a collection so it can be spliced into the result; a scalar element cannot be flattened.

Source

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

        Xform.of(this).take(start).concat(replacement).concat(Xform.of(this).drop(exclusiveEnd));
    return VmList.create(result);
  }

  @TruffleBoundary
  public final VmCollection flatten() {
    var builder = builder();
    for (var elem : this) {
      if (elem instanceof Iterable<?> iterable) {
        builder.addAll(iterable);
      } else if (elem instanceof VmListing listing) {
        listing.forceAndIterateMemberValues(
            (key, member, value) -> {
              builder.add(value);
              return true;
            });
      } else {
        CompilerDirectives.transferToInterpreter();
        throw new VmExceptionBuilder()
            .evalError("cannotFlattenCollectionWithNonCollectionElement")
            .withProgramValue("Element", elem)
            .build();
      }
    }
    return builder.build();
  }

  @TruffleBoundary
  public final VmCollection zip(VmCollection other) {
    var builder = builder();
    var iter1 = iterator();
    var iter2 = other.iterator();
    while (iter1.hasNext() && iter2.hasNext()) {
      builder.add(new VmPair(iter1.next(), iter2.next()));
    }
    return builder.build();
  }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Check the element reported under 'Element' and wrap it in a list (e.g. [elem]) or remove it
  2. Ensure all elements of the collection being flattened are List/ListSet/Mapping values
  3. Use a conditional/when branch to normalize scalar entries into single-element lists before flattening

Example fix

// before
flat = [[1,2], 3, [4]].flatten()
// after
flat = [[1,2], [3], [4]].flatten()
Defensive patterns

Strategy: validation

Validate before calling

const flattenable = xs.every(x => typeof x === 'object' && Array.isArray(x)); if (!flattenable) throw new TypeError('flatten requires all elements to be collections')

Type guard

const isNested = (xs) => Array.isArray(xs) && xs.every(Array.isArray);

Prevention

When it happens

Trigger: Calling collection.flatten() where at least one element is a non-collection value (e.g. an Int or String instead of a List/ListSet/Mapping). The offending element is attached as 'Element'.

Common situations: A list built conditionally where one branch appends a scalar instead of a nested list; data from external files where some entries are scalars.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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