apple/pkl · error · VmException

missingMapValue

missingMapValue

Error message

missingMapValue

What it means

Map constructors in Pkl take alternating key/value arguments. When the builder collects the key-value argument pairs and the count is odd, there is a key with no corresponding value, so it throws missingMapValue at the trailing span.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:1401

    if (elementNodes.first.length == 0) {
      return new ConstantValueNode(VmSet.EMPTY);
    }

    return elementNodes.second
        ? new ConstantValueNode(
            createSourceSection(expr), VmSet.createFromConstantNodes(elementNodes.first))
        : new SetLiteralNode(createSourceSection(expr), elementNodes.first);
  }

  private ExpressionNode doVisitMapLiteral(Expr expr, ArgumentList argList) {
    var keyAndValueNodes = createCollectionArgumentNodes(argList);

    if (keyAndValueNodes.first.length == 0) {
      return new ConstantValueNode(VmMap.EMPTY);
    }

    if (keyAndValueNodes.first.length % 2 != 0) {
      throw exceptionBuilder()
          .evalError("missingMapValue")
          .withSourceSection(createSourceSection(argList.span().stopSpan()))
          .build();
    }

    return keyAndValueNodes.second
        ? new ConstantValueNode(
            createSourceSection(expr), VmMap.createFromConstantNodes(keyAndValueNodes.first))
        : new MapLiteralNode(createSourceSection(expr), keyAndValueNodes.first);
  }

  private ExpressionNode doVisitBytesLiteral(Expr expr, ArgumentList argList) {
    var elementNodes = createCollectionArgumentBytesNodes(argList);

    if (elementNodes.first.length == 0) {
      return new ConstantValueNode(VmBytes.EMPTY);
    }
    return elementNodes.second

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Supply the missing value so arguments alternate key, value, key, value.
  2. Remove the dangling key if it was unintended.
  3. Prefer `new Map { ["k"] = v ... }` entry syntax to avoid positional alternation mistakes.

Example fix

// before
m = Map(1, "one", 2)
// after
m = Map(1, "one", 2, "two")
Defensive patterns

Strategy: validation

Validate before calling

// Validate Map(...) constructor argument count is even:
function validMapArgs(args) {
  return Array.isArray(args) && args.length % 2 === 0;
}

Type guard

const hasEvenEntries = (args: unknown[]): boolean => args.length % 2 === 0;

Prevention

When it happens

Trigger: Writing `Map(1, "one", 2)` — an odd number of arguments to a Map(...) constructor, leaving the last key without a value.

Common situations: Accidentally deleting a value while editing, or misusing the positional Map constructor expecting key-value pair syntax instead of flat alternation.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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