apple/pkl · error · VmException
cannotRenderProtobufMapKeyType
cannotRenderProtobufMapKeyType
Error message
cannotRenderProtobufMapKeyType
What it means
Protobuf map keys can only be integral, string, or boolean types. When the renderer resolves a `Mapping` type whose key type resolves to anything else (e.g. Int8/UInt16, DataSize, enum, or class types), it throws this error.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java:600
return resolveType(nullableType.getElementTypeNode());
} else if (type instanceof TypeAliasTypeNode typeAliasType) {
return resolveType(typeAliasType.getVmTypeAlias().getTypeNode());
} else if (type instanceof ListingTypeNode listingType) {
var valueType = resolveType(listingType.getValueTypeNode());
assert valueType != null : "Failed to resolve type node.";
type =
requiresWrapper()
? null
: new ListingTypeNode(
VmUtils.unavailableSourceSection(), VmLanguage.get(null), valueType);
return type;
} else if (type instanceof MappingTypeNode mappingType) {
var keyType = resolveType(mappingType.getKeyTypeNode());
if (!(keyType instanceof IntTypeNode
|| keyType instanceof StringTypeNode
|| keyType instanceof BooleanTypeNode)) {
throw new VmExceptionBuilder()
.evalError("cannotRenderProtobufMapKeyType")
.withSourceSection(type.getSourceSection())
.build();
}
var valueType = resolveType(mappingType.getValueTypeNode());
assert valueType != null : "Incomplete or malformed Mapping type";
mappingType =
new MappingTypeNode(
VmUtils.unavailableSourceSection(), VmLanguage.get(null), keyType, valueType);
type = requiresWrapper() ? null : mappingType;
return type;
} else if (type instanceof UnionTypeNode) {
// Some non-obvious normalization going on here:
// - A union type resolves to a union type, unless all element types are string or string
// literal types.
// - All element types are resolved also.
// - All string literal types are combined into a single String case.View on GitHub (pinned to f3efcbfc9b)
Solutions
- Change the map key type to `String` (most compatible) and encode structured keys as strings
- Use `Int` or `Boolean` keys if semantically appropriate
- Render to JSON/YAML instead of Protobuf, which allows arbitrary keys
- Pre-process the mapping into a Listing of entries with `key`/`value` properties
Example fix
// before ports: Mapping<Int16, String> // after ports: Mapping<String, String> // keys as strings, e.g. "8080" -> "http"
Defensive patterns
Strategy: validation
Validate before calling
function hasProtobufSafeKeys(m: Mapping): Boolean = m.keys.every((k) -> k is String || k is Int || k is Boolean)
Type guard
function protobufSafeMap(m: Mapping): Boolean = m.keys.every((k) -> k is String || k is Int || k is Boolean)
Prevention
- Key mappings with String (or Int/Boolean) only
- Convert enum/class keys to strings before rendering
- Encode structured keys (e.g. tuples) into a single string key
When it happens
Trigger: Rendering a `Mapping<K, V>` to Protobuf where K resolves to a type other than Int, String, or Boolean, e.g. `Mapping<Int128, String>` or a Listing/enum-keyed mapping.
Common situations: Maps keyed by enums, custom key classes, or wide integer types (Int8, UInt, Float) exported to protobuf.
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
- Node `%s` of type `%s` does not have a key named `%s`. Avail
- cannotResolveTypeForProtobuf
- invalidProtobufTopLevelValue
- cannotRenderTypeAddConverter
- cannotRenderProtobufMapKey
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/95e3f694b233abb8.
Report an issue: GitHub.