apple/pkl · error · VmTypeMismatchException
type mismatch: value is not of type Map
Error message
type mismatch: value is not of type Map
What it means
Thrown by the Map type-check node's executeLazily when a value checked against `Map<K,V>` is not a VmMap. Only VmMap instances proceed to the lazy key/value checks; anything else (List, Listing, Set, String, object, null) throws the typeMismatch error naming the `Map` type.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java:1512
}
}
public static final class MapTypeNode extends ObjectSlotTypeNode {
@Child private TypeNode keyTypeNode;
@Child private TypeNode valueTypeNode;
public MapTypeNode(SourceSection sourceSection, TypeNode keyTypeNode, TypeNode valueTypeNode) {
super(sourceSection);
this.keyTypeNode = keyTypeNode;
this.valueTypeNode = valueTypeNode;
}
@Override
protected Object executeLazily(VirtualFrame frame, Object value) {
if (value instanceof VmMap vmMap) {
return eval(frame, vmMap);
}
throw typeMismatch(value, BaseModule.getMapClass());
}
@Override
public Object executeEagerly(VirtualFrame frame, Object value) {
if (value instanceof VmMap vmMap) {
return evalEager(frame, vmMap);
}
throw typeMismatch(value, BaseModule.getMapClass());
}
@Override
public Object createDefaultValue(
VirtualFrame frame,
VmLanguage language,
SourceSection headerSection,
String qualifiedName) {
return VmMap.EMPTY;View on GitHub (pinned to f3efcbfc9b)
Solutions
- Produce an actual Map: `Map("k", 1, "k2", 2)` or keep the Map instead of extracting entries.
- If the value is an object, declare the property as `Mapping` instead of `Map`.
- If you called `.entries`/`.keys`/`.values`, use the original map or change the declared type to List.
- Convert pairs: `ListPair(...).toMap()` style APIs where available.
Example fix
// before counts: Map<String, Int> = countsMap.entries // List of pairs // after counts: Map<String, Int> = countsMap
Defensive patterns
Strategy: type-guard
Validate before calling
assert(m is Map<String, Int>, "expected Map<String, Int>")
Type guard
function asMap(v): Map<String, Int> = if (v is Map<String, Int>) v else Map()
Prevention
- Don't assign `map.entries`/`map.keys`/`map.values` (Lists) to Map-typed properties.
- Distinguish Map (literal key/value pairs) from Mapping (object).
- When ingesting YAML/JSON, build Maps explicitly.
When it happens
Trigger: A lazily-executed `Map<K,V>` constraint receives a non-Map value, e.g. `m: Map<String, Int> = List(1,2)` or assigning a Listing/object to a Map-typed property.
Common situations: Confusing `Map` with `Mapping` (objects with member syntax) or `List`/`Listing`; parsing external YAML/JSON where a key/value block became a list; using `Map(...).entries` result (a List) where the Map itself was expected.
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
- type mismatch: value does not conform to declared type (clas
- type mismatch: value's class is not a subclass of expected c
- type mismatch: value is not the expected string literal
- type mismatch: value is not of type Typed
- type mismatch: value is not of type Dynamic
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/06e896cb8ba52ac8.
Report an issue: GitHub.