BabylonJS/Babylon.js · error

Cannot compare ${a} and ${b}

Error message

Cannot compare ${a} and ${b}

What it means

ComparisonOperators is the shared implementation behind the comparison flow-graph blocks (<, <=, >, >=, ==, etc.). It only supports operands that pass isNumeric() — plain numbers or FlowGraphInteger values. If either operand is a boolean, string, vector, or any other FlowGraphTypes value, it throws 'Cannot compare ...' rather than guessing an ordering. Note FlowGraphEqualityBlock (==) reuses this helper, so equality checks on non-numeric values also throw.

Source

Thrown at packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.ts:790

        if (_AreSameVectorOrQuaternionClass(aClassName, bClassName) || _AreSameMatrixClass(aClassName, bClassName) || _AreSameIntegerClass(aClassName, bClassName)) {
            return (a as Vector3).equals(b as Vector3);
        }
        // Handle mixed number/FlowGraphInteger comparison
        if (isNumeric(a) && isNumeric(b)) {
            return getNumericValue(a as FlowGraphNumber) === getNumericValue(b as FlowGraphNumber);
        }
        if (typeof a !== typeof b) {
            return false;
        }
        return a === b;
    }
}

function ComparisonOperators(a: FlowGraphNumber, b: FlowGraphNumber, op: (a: number, b: number) => boolean) {
    if (isNumeric(a) && isNumeric(b)) {
        return op(getNumericValue(a), getNumericValue(b));
    } else {
        throw new Error(`Cannot compare ${a} and ${b}`);
    }
}

/**
 * Less than block.
 */
export class FlowGraphLessThanBlock extends FlowGraphBinaryOperationBlock<FlowGraphNumber, FlowGraphNumber, boolean> {
    constructor(config?: IFlowGraphBlockConfiguration) {
        super(RichTypeAny, RichTypeAny, RichTypeBoolean, (a, b) => this._polymorphicLessThan(a, b), FlowGraphBlockNames.LessThan, config);
    }

    private _polymorphicLessThan(a: FlowGraphNumber, b: FlowGraphNumber) {
        return ComparisonOperators(a, b, (a, b) => a < b);
    }
}

/**
 * Less than or equal block.

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Ensure both comparison inputs are numeric: insert extraction blocks (e.g. vector x/y/z extract) to compare components, or convert the value with Number(...) before it reaches the block.
  2. If you intended equality on non-numeric values, implement a custom flow graph block or compare via dedicated blocks instead of reusing the numeric comparison block.
  3. Check upstream block types in the graph editor and correct the mis-wired connection feeding the comparison block.

Example fix

// before: comparing a boolean and a number
const cmp = new FlowGraphLessThanBlock();
cmp.a.connect(logicBlock.output); // boolean -> throws

// after: extract a numeric value or coerce first
const cmp = new FlowGraphLessThanBlock();
cmp.a.connect(Number(...)); // number
// or compare vector components:
cmp.a.connect(vecExtractBlock.x);
Defensive patterns

Strategy: type-guard

Validate before calling

// before the comparison block executes
function numericOperands(a, b) {
  const ok = (v) => typeof v === 'number' || (typeof v === 'object' && v !== null && 'value' in v);
  return ok(a) && ok(b);
}
if (!numericOperands(cmpInputA, cmpInputB)) throw new TypeError('Comparison inputs must be numeric');

Type guard

function isNumericValue(v): v is number | FlowGraphInteger {
  return typeof v === 'number' || (typeof v === 'object' && v !== null && 'value' in v && typeof (v as any).value === 'number');
}

Try / catch

try {
  result = comparisonBlock.evaluate(context);
} catch (e) {
  if (e.message.startsWith('Cannot compare')) {
    // inspect and coerce inputs to numbers, then retry
    result = Number(a) < Number(b);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Connecting a non-numeric output (boolean from a logic block, a string, or a Vector3/Quaternion) into either input of a comparison block (less-than, greater-than, equality, etc.) and executing the flow graph.

Common situations: Comparing a boolean result of a logical AND block with a number; accidentally wiring a vector output into a comparison block; comparing strings expecting lexicographic order which the block does not support.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/3c06ff699687e02f. Report an issue: GitHub.