apple/pkl · error

wrongListingKeyType

wrongListingKeyType

Error message

wrongListingKeyType ${type}

What it means

Thrown when a `Listing` is amended with an entry whose key is not a non-negative integer index. Listing keys must be integers (the next element index); if the key expression evaluates to any other type (String, Float, etc.) this error reports the key's actual type.

Solutions

  1. Use integer indices for Listing keys (or the empty-key shorthand `[*]` / `_` for the next index)
  2. Switch the parent to a `Mapping` if string keys are required
  3. Fix the key expression to evaluate to an `Int`
  4. Check the amendment site — the error location points at the key node

Example fix

// before
list = new Listing { ["first"] = 1 }
// after
list = new Listing { [0] = 1 }
Defensive patterns

Strategy: validation

Validate before calling

function isValidListingKey(k) { return Number.isInteger(k) && k >= 0 }

Type guard

function isIntKey(k) { return typeof k === 'number' && Number.isInteger(k) }

Prevention

When it happens

Trigger: Amending a Listing with `["key"] = value` or `[1.5] = value` — the key node's `executeInt` throws UnexpectedResultException and the actual key type is reported.

Common situations: Copy-pasting Mapping entry syntax into a Listing amendment, using string keys expecting map-like behavior, JSON with mixed arrays/objects converted incorrectly.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorEntryNode.java:95

  @Fallback
  @SuppressWarnings("unused")
  void fallback(Object parent, ObjectData data) {
    CompilerDirectives.transferToInterpreter();
    throw exceptionBuilder().evalError("objectCannotHaveEntry", parent).build();
  }

  private void addRegularEntry(VirtualFrame frame, ObjectData data) {
    var key = keyNode.executeGeneric(frame);
    data.addMember(frame, key, member, this);
  }

  private void addListingEntry(VirtualFrame frame, ObjectData data, int parentLength) {
    long index;
    try {
      index = keyNode.executeInt(frame);
    } catch (UnexpectedResultException e) {
      CompilerDirectives.transferToInterpreter();
      throw exceptionBuilder()
          .evalError("wrongListingKeyType", new ProgramValue("", VmUtils.getClass(e.getResult())))
          .withLocation(keyNode)
          .build();
    }

    // use same error messages as in checkIsValidListingAmendment and checkMaxListingMemberIndex
    if (index < 0 || index >= parentLength) {
      CompilerDirectives.transferToInterpreter();
      throw exceptionBuilder()
          .evalError("elementIndexOutOfRange", index, 0, parentLength - 1)
          .withLocation(keyNode)
          .build();
    }

    data.addMember(frame, index, member, this);
  }
}

View on GitHub (pinned to f3efcbfc9b)