apple/pkl · error
operatorNotDefinedLeft
operatorNotDefinedLeft
Error message
operatorNotDefinedLeft ${op} ${leftClass} What it means
Short-circuiting nodes (`&&`, `||`) require the left operand to be Boolean; when no specialization matches the left type, the fallback throws `operatorNotDefinedLeft` naming the operator and the left operand's class. Unlike 542/543 (right side), here the LEFT side of the logical operator is not a Boolean.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/binary/ShortCircuitingExpressionNode.java:44
/**
* A binary expression whose right operand may be short-circuited. Does not inherit from
* BinaryExpressionNode for technical reasons.
*/
@NodeChild(value = "leftNode", type = ExpressionNode.class)
public abstract class ShortCircuitingExpressionNode extends ExpressionNode {
@Child protected ExpressionNode rightNode;
protected abstract ExpressionNode getLeftNode();
protected ShortCircuitingExpressionNode(SourceSection sourceSection, ExpressionNode rightNode) {
super(sourceSection);
this.rightNode = rightNode;
}
@Fallback
@TruffleBoundary
protected Object fallback(Object left) {
throw operatorNotDefined(left);
}
@TruffleBoundary
protected VmException operatorNotDefined(Object left) {
return exceptionBuilder()
.evalError("operatorNotDefinedLeft", getShortName(), VmUtils.getClass(left))
.withProgramValue("Left operand", left)
.build();
}
@TruffleBoundary
protected VmException operatorNotDefined(Object left, Object right) {
return exceptionBuilder()
.evalError(
"operatorNotDefined2", getShortName(), VmUtils.getClass(left), VmUtils.getClass(right))
.withProgramValue("Left operand", left)
.withProgramValue("Right operand", right)
.build();View on GitHub (pinned to f3efcbfc9b)
Solutions
- Fix the left operand to be a Boolean expression
- Add the missing comparison that converts the value to Boolean
- Annotate the source property as Boolean
Example fix
// before (Pkl) val ok = retries && retries > 3 // after val ok = retries > 0 && retries > 3
Defensive patterns
Strategy: type-guard
Validate before calling
function isValidLeftOperand(left) { return typeof left === 'boolean'; } Type guard
const isBool = (v) => typeof v === 'boolean';
Prevention
- Check the LEFT side of &&/|| is a Boolean expression
- Fix inverted or missing comparisons
- Type-annotate source properties as Boolean
When it happens
Trigger: `<nonBoolean> && ...` or `<nonBoolean> || ...`, e.g. `1 && true`, `"yes" || false`, or a lazily-evaluated left property of wrong type.
Common situations: Condition written against a config property whose type changed (Int/String instead of Boolean), or inverted/missing comparison.
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
- operatorNotDefined2
- operatorNotDefined2
- operatorNotDefined2
- operatorNotDefined1
- Node `%s` of type `%s` does not have a property named `%s`.
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/38491dd5e88f6ac3.
Report an issue: GitHub.