apple/pkl · error · VmException
cannotRenderProtobufMapKey
cannotRenderProtobufMapKey
Error message
cannotRenderProtobufMapKey
What it means
Protobuf map keys must be directives, Long, Boolean, or String; the renderer found a map entry key of another type (e.g. a Double, IntSeq, or arbitrary object) and aborts, attaching the offending key as program value.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java:313
visit(value);
var popped = wrapperRequirement.pop();
assert popped : "Corrupted traversal stack.";
if (addedType) {
propertyPath.pop();
endMessage();
}
if (requiresWrapper()) {
propertyPath.pop();
}
}
@Override
protected void visitEntryKey(Object key, boolean isFirst) {
var isDirective = isRenderDirective(key);
var isValidKey =
isDirective || key instanceof Long || key instanceof Boolean || key instanceof String;
if (!isValidKey) {
throw new VmExceptionBuilder()
.evalError("cannotRenderProtobufMapKey")
.withProgramValue("Key", key)
.build();
}
writePropertyName();
startMessage();
startNewLine();
builder.append("key: ");
if (isDirective) {
builder.append(VmUtils.readTextProperty(key));
} else if (key instanceof String string) {
builder.append('"').append(jsonEscaper.escape(string)).append('"');
} else {
builder.append(key);
}
}
@OverrideView on GitHub (pinned to f3efcbfc9b)
Solutions
- Change map keys to String (or Long/Boolean), e.g. `["1.0"]` instead of `[1.0]`
- Convert key values before rendering (`key.toString()` / integer literals without decimal point)
- Exclude or transform non-conforming entries before protobuf rendering
Example fix
// before
value = new Mapping { [1.0] = "a" }
// after
value = new Mapping { ["1"] = "a" } Defensive patterns
Strategy: validation
Validate before calling
function hasValidMapKeys(m) { return Object.values(m).every((entry) => typeof entry.key === 'string' || typeof entry.key === 'boolean' || Number.isInteger(entry.key)); } Type guard
const isProtobufMapKey = (k) => typeof k === 'string' || typeof k === 'boolean' || Number.isInteger(k);
Try / catch
try { renderAsProtobuf(value) } catch (e) { if (e.code === 'cannotRenderProtobufProtobufKey' || e.code === 'cannotRenderProtobufMapKey') { /* coerce keys to String/Long */ } else throw e } Prevention
- Use String/Long/Boolean keys in Mappings rendered to protobuf
- Write integer literals without a decimal point to avoid Double keys
- Audit map keys of imported/converted data before protobuf rendering
When it happens
Trigger: Rendering a Mapping/Map to protobuf whose keys are not Long/Boolean/String — e.g. float keys, keys that are objects, or Defaultable/other Vm wrapper keys not recognized as directives.
Common situations: Using Pkl Mappings with non-string keys (numbers as Double from `1.0` literal, booleans via bracket syntax that resolves oddly) and rendering to protobuf; JSON-imported maps with numeric keys parsed as doubles.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- cannotResolveTypeForProtobuf
- invalidProtobufTopLevelValue
- cannotRenderTypeAddConverter
- Values of type `Duration` cannot be rendered as JSON. Value:
- Values of type `DataSize` cannot be rendered as JSON. Value:
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/7e36dd2fe465c1e6.
Report an issue: GitHub.