apple/pkl · error · VmException

expectedNonEmptyListing

expectedNonEmptyListing

Error message

expectedNonEmptyListing

What it means

Listing members `first`, `last`, and similar single-value accessors are only defined for non-empty listings. checkNonEmpty throws expectedNonEmptyListing when one of these members is accessed on an empty Listing. The error is reported at the accessing node's location.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java:332

  }

  public abstract static class toSet extends ExternalMethod0Node {
    @Specialization
    protected VmSet eval(VmListing self) {
      var builder = VmSet.EMPTY.builder();
      self.forceAndIterateMemberValues(
          (key, member, value) -> {
            builder.add(value);
            return true;
          });
      return builder.build();
    }
  }

  private static void checkNonEmpty(VmListing self, PklNode node) {
    if (self.isEmpty()) {
      CompilerDirectives.transferToInterpreter();
      throw new VmExceptionBuilder()
          .evalError("expectedNonEmptyListing")
          .withLocation(node)
          .build();
    }
  }

  private static void checkSingleton(VmListing self, PklNode node) {
    if (self.getLength() != 1) {
      CompilerDirectives.transferToInterpreter();
      throw new VmExceptionBuilder()
          .evalError("expectedSingleElementListing")
          .withLocation(node)
          .build();
    }
  }
}

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Check `listing.isEmpty` before accessing first/last and handle the empty case explicitly.
  2. Ensure upstream data actually populates the listing (fix the source/filter producing zero elements).
  3. Provide a default when empty: `if (items.isEmpty) default else items.first`.
  4. Use `items.toList()` and standard guards if doing complex access in code.

Example fix

// before
name = files.first

// after
name = if (files.isEmpty) "default.txt" else files.first
Defensive patterns

Strategy: type-guard

Validate before calling

// guard before single-value access
if (!items.isEmpty) { /* safe to use items.first */ }

Type guard

function firstOrNull(l: Listing) = if (l.isEmpty) null else l.first

Try / catch

try { x = items.first } catch (e) { if (e.message.contains('expectedNonEmptyListing')) x = fallback else throw e }

Prevention

When it happens

Trigger: Accessing `someListing.first`, `someListing.last` (or similar non-empty-required members) on a Listing with zero elements.

Common situations: A filtered/parsed input produced an empty list (e.g. no matching files, empty config list) and code assumes at least one item; reading required lists from external data that can legitimately be empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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