apple/pkl · error · VmException

duplicateDefinition

duplicateDefinition

Error message

Duplicate definition of member `{0}`.

What it means

Pkl throws `duplicateDefinition` when two members resolve to the same key/index within one object literal. In addListEntries, `EconomicMaps.put(result, index, value)` returning non-null means two element expressions amended the same element index, so Pkl refuses the ambiguous definition.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/literal/SpecializedObjectLiteralNode.java:255

            .evalError("wrongListingKeyType", new ProgramValue("", VmUtils.getClass(e.getResult())))
            .withSourceSection(keyNodes[i].getSourceSection())
            .build();
      }

      var value = values[i];

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

      if (EconomicMaps.put(result, index, value) != null) {
        CompilerDirectives.transferToInterpreter();
        throw exceptionBuilder()
            .evalError("duplicateDefinition", new ProgramValue("", index))
            .withSourceSection(value.getHeaderSection())
            .build();
      }
    }
  }

  @TruffleBoundary
  protected @Nullable ObjectMember findFirstNonProperty(
      UnmodifiableEconomicMap<Object, ObjectMember> members) {
    var cursor = EconomicMaps.getEntries(members);
    while (cursor.advance()) {
      var member = cursor.getValue();
      if (member.getNameOrNull() == null) return member;
    }
    return null;
  }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Remove one of the conflicting `[n]` amendments for that index.
  2. Merge the two element bodies into a single `[n]` amendment.
  3. If using a spread (`...`), verify which indices it already provides before adding explicit amendments.

Example fix

// before
obj {
  elements {
    [0] { name = "a" }
    [0] { name = "b" } // duplicate
  }
}
// after
obj {
  elements {
    [0] { name = "b" }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Pkl: track indices you amend
indices = Set(0, 2)
assert(indices.length == 2, "duplicate element index in amendment")

Prevention

When it happens

Trigger: Two `[n]` element amendments with the same index inside one amending object literal; spread/`...` plus an explicit `[n]` that collides with an index already produced by the spread.

Common situations: Merging listing amendments where a spread already covers index 0 and an explicit `[0]` is also written; generated or templated code emitting the same index twice.

Related errors


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