apple/pkl · error · RendererException

Values of type `Class` cannot be rendered as YAML. Value: %s

Error message

Values of type `Class` cannot be rendered as YAML. Value: %s

What it means

Classes are type declarations, not data, so YamlRenderer.visitClass throws RendererException rather than emitting a class value. Only the class's simple name is included in the message. Modules render fine, but class references must be removed or converted before YAML output.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/YamlRenderer.java:202

      @SuppressWarnings("unchecked")
      var mapValue = (Map<String, ?>) value;
      doVisitProperties(mapValue);
    }

    @Override
    public void visitObject(PObject value) {
      doVisitProperties(value.getProperties());
    }

    @Override
    public void visitModule(PModule value) {
      doVisitProperties(value.getProperties());
    }

    @Override
    public void visitClass(PClass value) {
      throw new RendererException(
          String.format(
              "Values of type `Class` cannot be rendered as YAML. Value: %s",
              value.getSimpleName()));
    }

    @Override
    public void visitTypeAlias(TypeAlias value) {
      throw new RendererException(
          String.format(
              "Values of type `TypeAlias` cannot be rendered as YAML. Value: %s",
              value.getSimpleName()));
    }

    @Override
    public void visitNull() {
      emitter.emit(YamlUtils.plainScalar("null", Tag.NULL));
    }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Remove class references from the rendered value; render instances or a descriptive string (e.g. `Foo.getSimpleName()`) instead.
  2. Restructure the Pkl module so `output.value` contains only data (amendments/objects), not type declarations.
  3. Filter out non-data values before handing the tree to the renderer.

Example fix

// before
renderer.renderDocument(Map("type", SomeClass)); // throws
// after
renderer.renderDocument(Map("type", SomeClass.getSimpleName()));
Defensive patterns

Strategy: type-guard

Validate before calling

void requireNoClasses(Object v) {
  if (v instanceof PClass) throw new IllegalArgumentException("class value not renderable: " + ((PClass) v).getSimpleName());
}

Type guard

boolean isDataValue(Object v) { return !(v instanceof PClass); }

Try / catch

try {
  renderer.renderDocument(value);
} catch (RendererException e) {
  if (e.getMessage().startsWith("Values of type `Class` cannot be rendered as YAML")) {
    renderer.renderDocument(stripClassRefs(value));
  } else throw e;
}

Prevention

When it happens

Trigger: renderDocument on a value tree that contains a PClass reference, e.g. a property holding `Foo` (a class) or output containing default-bearing class references, reaching visitClass.

Common situations: Pkl modules whose output accidentally exposes a class (e.g. `output { value { myClass = Foo } }`); reflective/generic pipelines that walk all properties including type references.

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/c1420655ab9d65e1. Report an issue: GitHub.