apple/pkl · error · VmException
cannotExportValue
cannotExportValue
Error message
cannotExportValue
What it means
VmFunction.export() always throws an evalError 'cannotExportValue': function values have no externalizable representation, so forcing a function into an exported/host value (e.g. as module output or via PValue conversion) is unsupported. The input at fault is a Function-typed value placed where a data value is expected.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/runtime/VmFunction.java:179
@Override
public VmClass getVmClass() {
return BaseModule.getFunctionNClass(paramCount);
}
@Override
public void force(boolean allowUndefinedValues, boolean recurse) {
// do nothing
}
@Override
public void force(boolean allowUndefinedValues) {
// do nothing
}
@Override
public Object export() {
throw new VmExceptionBuilder().evalError("cannotExportValue", getVmClass()).build();
}
@Override
public void accept(VmValueVisitor visitor) {
visitor.visitFunction(this);
}
@Override
public <T> T accept(VmValueConverter<T> converter, Iterable<Object> path) {
return converter.convertFunction(this, path);
}
@Override
public boolean equals(Object obj) {
return this == obj;
}
@OverrideView on GitHub (pinned to f3efcbfc9b)
Solutions
- Export a plain data value instead of a function (e.g. call the function and output its result).
- Remove functions from the `output.value` of modules consumed externally.
Example fix
// before
output { value = toUpper }
// after
output { value = toUpper("hello") } Defensive patterns
Strategy: validation
Validate before calling
if (typeof output.value === 'function') throw new Error('cannot export a function; call it and export the result') Type guard
const isExportable = (v) => v === null || ['string','number','boolean'].includes(typeof v) || Array.isArray(v) || (typeof v === 'object' && !('call' in v)); Try / catch
try { module.export() } catch (e) { if (e.code === 'cannotExportValue') { console.error('output contains a function:', e.vmClass) } throw e } Prevention
- Never assign a function directly to output.value
- Call functions when building the exported value
- Keep exported objects free of function-typed properties
When it happens
Trigger: A module's output contains a function value, e.g. `output { value = someFunction }` or a top-level binding that resolves to a function when the module is evaluated/exported (via pkl CLI or the Java API export()).
Common situations: Assigning a function to `output.value` by mistake; exporting an object whose property is a function; accidentally referencing a function name without calling it.
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
- cannotExportValue
- tooManyFunctionParameters
- Node `%s` of type `%s` does not have a property named `%s`.
- JavaType token must be parameterized.
- Leaf node `%s` of type `%s` does not have a child named `%s`
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/0c488b5cd5fb2ce4.
Report an issue: GitHub.