apple/pkl · error · VmTypeMismatchException
type mismatch: value is not of type String
Error message
type mismatch: value is not of type String
What it means
The String typecheck node's executeLazily accepts a value only if it is a Java String (Pkl String); anything else fails with 'type mismatch: value is not of type String' via typeMismatch(value, BaseModule.getStringClass()). Pkl does not coerce numbers/booleans to strings implicitly.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java:3042
return other instanceof AnyTypeNode;
}
@Override
protected boolean acceptTypeNode(boolean visitTypeArguments, TypeNodeConsumer consumer) {
return consumer.accept(this);
}
}
public static final class StringTypeNode extends ObjectSlotTypeNode {
public StringTypeNode(SourceSection sourceSection) {
super(sourceSection);
}
@Override
protected Object executeLazily(VirtualFrame frame, Object value) {
if (value instanceof String) return value;
throw typeMismatch(value, BaseModule.getStringClass());
}
@Override
public VmClass getVmClass() {
return BaseModule.getStringClass();
}
@Override
public boolean doIsEquivalentTo(TypeNode other) {
return other instanceof StringTypeNode;
}
@Override
protected boolean acceptTypeNode(boolean visitTypeArguments, TypeNodeConsumer consumer) {
return consumer.accept(this);
}
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Convert explicitly with `.toString()` or string interpolation `"\(value)"`
- Fix the source value to be a string (quote it in the imported data)
- Relax the declaration type if a non-string is legitimate (e.g. `String|Int`)
- Validate with `v is String` before assignment
Example fix
// before name: String = 42 // after name: String = "42" // or name: String|Int = 42
Defensive patterns
Strategy: validation
Validate before calling
// pkl: assert(value is String)
function isString(v) { return typeof v === 'string'; } Type guard
function isString(v) { return typeof v === 'string'; } Try / catch
try { checkString(value); } catch (e) { log(`expected String, got ${typeof value}: ${value}`); throw e; } Prevention
- Quote values in imported YAML/JSON when they must be strings
- Use string interpolation "\(x)" instead of raw non-string values
- Coerce env/CLI inputs with .toString() before assignment
When it happens
Trigger: Assigning a number, Boolean, null, or object to a property typed String, e.g. `name: String = 42` or an imported JSON field that is a number.
Common situations: JSON/YAML imports where a field is sometimes numeric (`port: 8080`); interpolation forgotten (using `x` instead of `"\(x)"`); env-var substitution yielding null.
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
- Cannot convert pkl.base#String `%s` to java.lang.Character b
- Error converting property `%s` in Pkl object of type `%s` to
- The top-level value of a YAML stream must have type `Collect
- type constraint mismatch
- type mismatch
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/032eb5766d790ec7.
Report an issue: GitHub.