apple/pkl · error · VmException

unseparatedObjectMembers

unseparatedObjectMembers

Error message

unseparatedObjectMembers

What it means

Object members (properties, entries, elements) in a Pkl object must be separated by whitespace/newlines or commas where required. The builder checks the source spans of consecutive members; if one span is directly adjacent to the next (no separator between them), it rejects the object body.

Source

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

              currentScope.getQualifiedName(),
              currentScope.isCustomThisScope(),
              parametersDescriptor,
              parameterTypes,
              members,
              parentNode);
        });
  }

  private void checkSpaceSeparatedObjectMembers(ObjectBody objectBody) {
    var members = objectBody.getMembers();
    if (members.size() < 2) {
      return;
    }
    var previous = members.get(0).span();
    for (var i = 1; i < members.size(); i++) {
      var member = members.get(i);
      if (previous.adjacent(member.span())) {
        throw exceptionBuilder()
            .evalError("unseparatedObjectMembers")
            .withSourceSection(createSourceSection(member.span()))
            .build();
      }
      previous = member.span();
    }
  }

  private ObjectMember doVisitObjectProperty(ObjectProperty prop) {
    var modifierNodes = prop.getModifiers();
    var propertyName = prop.getIdentifier();
    var modifiers =
        doVisitModifiers(
            modifierNodes, VmModifier.VALID_OBJECT_MEMBER_MODIFIERS, "invalidObjectMemberModifier");
    if (VmModifier.isConst(modifiers) && !VmModifier.isLocal(modifiers)) {
      @SuppressWarnings("OptionalGetWithoutIsPresent")
      var constModifierCtx =
          modifierNodes.stream()

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Insert a newline or space between the two adjacent members.
  2. If generating config programmatically, always emit a separator (e.g. `\n`) between members.
  3. Check for an unclosed value immediately before the member that swallowed the separator.

Example fix

// before
foo = 1bar = 2
// after
foo = 1
bar = 2
Defensive patterns

Strategy: validation

Validate before calling

// when generating object bodies, always join members with a separator
const body = members.join('\n');
if (/(\S)([\[\"a-zA-Z])/.test(body.replace(/=.*/g, ''))) reviewSeparators();

Prevention

When it happens

Trigger: Two object members written with no separating whitespace or newline, e.g. `{foo = 1bar = 2}` or adjacent entries `{["a"] = 1["b"] = 2}`; the check uses `previous.adjacent(member.span())` over the collected member spans.

Common situations: Minifying/generated config output that strips whitespace; line-join accidents when pasting or when an editor collapses lines; template-generated object literals without newline separators.

Related errors


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