apple/pkl · error · VmException

invalidPropertiesTopLevelValue

invalidPropertiesTopLevelValue

Error message

invalidPropertiesTopLevelValue

What it means

The Java `.properties` renderer accepts only Map, Typed, Mapping, or Dynamic values at the top level. Anything else (Listing, List, scalars) cannot be flattened into key=value properties, so the error reports the offending class.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/PropertiesRendererNodes.java:155

      cannotRenderTypeAddConverter(value);
    }

    @Override
    public void visitNull(VmNull value) {
      if (isDocument) {
        writeKey();
        writeSeparator();
        writeLineBreak();
      }
    }

    @Override
    protected void visitDocument(Object value) {
      if (!(value instanceof VmMap
          || value instanceof VmTyped
          || value instanceof VmMapping
          || value instanceof VmDynamic)) {
        throw new VmExceptionBuilder()
            .evalError("invalidPropertiesTopLevelValue", VmUtils.getClass(value))
            .withProgramValue("Value", value)
            .build();
      }
      if (!isRenderDirective(value)) {
        isDocument = true;
      }
      visit(value);
    }

    @Override
    protected void visitTopLevelValue(Object value) {
      if ((value instanceof VmMap
              || value instanceof VmTyped
              || value instanceof VmMapping
              || value instanceof VmDynamic)
          && !isRenderDirective(value)) {
        cannotRenderTypeAddConverter((VmValue) value);

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Flatten the collection into a Mapping/Dynamic with string keys, e.g. `new Mapping { ["0"] = x; ... }`
  2. Use `toMap()`/key-value conversion on the listing before rendering
  3. Render to a format that supports the value's actual type (JSON, YAML, Pcf)

Example fix

// before
output.value = new Listing { "a"; "b" }
output.renderer = new PropertiesRenderer
// after
output.value = new Mapping { ["0"] = "a"; ["1"] = "b" }
output.renderer = new PropertiesRenderer
Defensive patterns

Strategy: validation

Validate before calling

function isPropertiesTopLevel(v) { return isPklMap(v) || isPklTyped(v) || isPklMapping(v) || isPklDynamic(v); }

Type guard

const isPropertiesRenderable = (v) => isPklMap(v) || isPklTyped(v) || isPklMapping(v) || isPklDynamic(v);

Try / catch

try { renderAsProperties(value) } catch (e) { if (e.code === 'invalidPropertiesTopLevelValue') { /* flatten to Mapping */ } else throw e }

Prevention

When it happens

Trigger: Rendering a Listing/List, IntSeq, or scalar as the top-level value of a `.properties` output, e.g. `output.text = myList.renderAsProperties()` where the value is not Map/Typed/Mapping/Dynamic.

Common situations: Producing Java properties files from Pkl but assigning a list or primitive to `output.value`; refactoring a module so `output.value` changed type from Dynamic to Listing.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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