{"record":{"id":"bea2e22604ce8172","repo":"BabylonJS/Babylon.js","slug":"cannot-perform-bitwise-xor-on-a-and-b","errorCode":null,"errorMessage":"Cannot perform bitwise XOR on ${a} and ${b}","messagePattern":"Cannot perform bitwise XOR on (.+?) and (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.ts","lineNumber":1281,"sourceCode":"\r\n/**\r\n * Bitwise XOR operation\r\n */\r\nexport class FlowGraphBitwiseXorBlock extends FlowGraphBinaryOperationBlock<FlowGraphBitwiseTypes, FlowGraphBitwiseTypes, FlowGraphBitwiseTypes> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            getRichTypeByFlowGraphType(config?.valueType || FlowGraphTypes.Integer),\r\n            (a, b) => {\r\n                if (typeof a === \"boolean\" && typeof b === \"boolean\") {\r\n                    return a !== b;\r\n                } else if (typeof a === \"number\" && typeof b === \"number\") {\r\n                    return a ^ b;\r\n                } else if (typeof a === \"object\" && typeof b === \"object\") {\r\n                    return new FlowGraphInteger(a.value ^ b.value);\r\n                } else {\r\n                    throw new Error(`Cannot perform bitwise XOR on ${a} and ${b}`);\r\n                }\r\n            },\r\n            FlowGraphBlockNames.BitwiseXor,\r\n            config\r\n        );\r\n    }\r\n}\r\n\r\n/**\r\n * Bitwise left shift operation\r\n */\r\nexport class FlowGraphBitwiseLeftShiftBlock extends FlowGraphBinaryOperationBlock<FlowGraphInteger, FlowGraphInteger, FlowGraphInteger> {\r\n    constructor(config?: IFlowGraphBlockConfiguration) {\r\n        super(\r\n            RichTypeFlowGraphInteger,\r\n            RichTypeFlowGraphInteger,\r\n            RichTypeFlowGraphInteger,\r\n            (a, b) => new FlowGraphInteger(a.value << b.value),\r","sourceCodeStart":1263,"sourceCodeEnd":1299,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphMathBlocks.pure.ts#L1263-L1299","documentation":"The BitwiseXor flow graph block supports exactly three shapes: two booleans (a !== b), two plain numbers (a ^ b), or two FlowGraphInteger objects (a.value ^ b.value). Mixed kinds or any other type (string, vector, object other than FlowGraphInteger) reaches the throw. The two operands must share the same representation.","triggerScenarios":"Executing FlowGraphBitwiseXorBlock with mismatched inputs: boolean XOR number, number XOR FlowGraphInteger, FlowGraphInteger XOR boolean, or a non-supported value type on either port.","commonSituations":"Toggling a boolean flag with a numeric mask in one block; an upstream block changed from returning number to FlowGraphInteger (or vice versa) after an engine upgrade; copy-pasted graph wiring with inconsistent types.","solutions":["Match operand types: use two booleans for logical XOR, or two numbers / two FlowGraphInteger for bitwise XOR.","Convert one operand: use intBlock.value.value (number) or wrap the number in new FlowGraphInteger(n).","Audit the graph connections feeding the block and fix the wrong-typed wire."],"exampleFix":"// before: FlowGraphInteger XOR boolean -> throws\nxorBlock.a.connect(intBlock.value); // FlowGraphInteger\nxorBlock.b.connect(toggleBlock.output); // boolean\n\n// after: both FlowGraphInteger\nxorBlock.a.connect(intBlock.value);\nxorBlock.b.connect(new FlowGraphInteger(toggleBlock.output ? 1 : 0));","handlingStrategy":"type-guard","validationCode":"// before BitwiseXor block runs\nfunction bitwiseCompatible(a, b) {\n  const bool = (v) => typeof v === 'boolean';\n  const num = (v) => typeof v === 'number';\n  const int = (v) => typeof v === 'object' && v !== null && 'value' in v;\n  return (bool(a) && bool(b)) || (num(a) && num(b)) || (int(a) && int(b));\n}\nif (!bitwiseCompatible(xorInputA, xorInputB)) throw new TypeError('Bitwise XOR needs two booleans, two numbers, or two FlowGraphIntegers');","typeGuard":"function isFlowGraphInteger(v): v is FlowGraphInteger {\n  return typeof v === 'object' && v !== null && 'value' in v && typeof (v as any).value === 'number';\n}\nfunction sameOperandKind(a: unknown, b: unknown): boolean {\n  return isFlowGraphInteger(a) === isFlowGraphInteger(b) && typeof a === typeof b;\n}","tryCatchPattern":"try {\n  result = xorBlock.evaluate(context);\n} catch (e) {\n  if (e.message.startsWith('Cannot perform bitwise XOR')) {\n    result = toNum(a) ^ toNum(b); // normalize then retry\n  } else { throw e; }\n}","preventionTips":["For boolean toggling use !== in a logic block, not BitwiseXor with mixed types.","Convert one side explicitly (new FlowGraphInteger(n) or .value) whenever integer and plain-number domains meet.","Audit copied/pasted graph sections for inconsistent operand representations."],"tags":["babylonjs","flow-graph","bitwise","type-mismatch"],"backgroundTag":"bitwise-operand-type-mismatch","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}