apple/pkl · error · RendererException

Maps with non-String keys cannot currently be rendered as YA

Error message

Maps with non-String keys cannot currently be rendered as YAML. Key: %s

What it means

YAML mapping keys here are restricted to strings; complex mapping keys (numbers, booleans, nested collections) are not supported by the renderer. visitMap pre-scans keys and throws RendererException on the first non-String key.

Source

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

      doVisitIterable(value, null);
    }

    @Override
    public void visitList(List<?> value) {
      doVisitIterable(value, null);
    }

    @Override
    public void visitSet(Set<?> value) {
      doVisitIterable(value, "!!set");
    }

    @Override
    public void visitMap(Map<?, ?> value) {
      for (var key : value.keySet()) {
        if (!(key instanceof String)) {
          // http://stackoverflow.com/questions/33987316/what-is-a-complex-mapping-key-in-yaml
          throw new RendererException(
              String.format(
                  "Maps with non-String keys cannot currently be rendered as YAML. Key: %s", key));
        }
      }

      @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());

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Convert non-String keys to strings before rendering: Map("1", value) or keys.toString().
  2. Restructure the data as a List of {key, value} objects instead of a keyed map.
  3. Fix the Pkl module to use String keys (e.g. quote the keys) if the source is Pkl code.

Example fix

// before
renderer.renderDocument(Map(8080, "http")); // throws
// after
renderer.renderDocument(Map("8080", "http"));
Defensive patterns

Strategy: validation

Validate before calling

void requireStringKeys(Map<?, ?> m) {
  for (var k : m.keySet()) {
    if (!(k instanceof String)) throw new IllegalArgumentException("non-String key: " + k);
  }
}

Type guard

boolean hasOnlyStringKeys(Map<?, ?> m) { return m.keySet().stream().allMatch(String.class::isInstance); }

Try / catch

try {
  renderer.renderDocument(map);
} catch (RendererException e) {
  if (e.getMessage().contains("Maps with non-String keys")) {
    renderer.renderDocument(stringKeyify(map)); // keys -> String.valueOf(k)
  } else throw e;
}

Prevention

When it happens

Trigger: renderDocument on a Map (or Pkl Mapping) with non-String keys such as Map(1, "a") or Map(true, ...) — the key scan in visitMap fails.

Common situations: Pkl objects using Int/Boolean keys (e.g. port-number keyed maps) exported to YAML; generic Map built programmatically with Integer keys; JSON-to-YAML pipelines where parsed numeric keys survived.

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