{"record":{"id":"cabe67a05c97a70a","repo":"BabylonJS/Babylon.js","slug":"cannot-get-dot-product-of-a-and-b","errorCode":null,"errorMessage":"Cannot get dot product of ${a} and ${b}","messagePattern":"Cannot get dot product of (.+?) and (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.ts","lineNumber":162,"sourceCode":"/**\n * Dot product block.\n */\nexport class FlowGraphDotBlock extends FlowGraphBinaryOperationBlock<FlowGraphVector, FlowGraphVector, number> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeAny, RichTypeAny, RichTypeNumber, (a, b) => this._polymorphicDot(a, b), FlowGraphBlockNames.Dot, config);\n    }\n\n    private _polymorphicDot(a: FlowGraphVector, b: FlowGraphVector) {\n        const className = _GetClassNameOf(a);\n        switch (className) {\n            case FlowGraphTypes.Vector2:\n            case FlowGraphTypes.Vector3:\n            case FlowGraphTypes.Vector4:\n            case FlowGraphTypes.Quaternion:\n                // casting is needed because dot requires both to be the same type\n                return (a as Vector3).dot(b as Vector3);\n            default:\n                throw new Error(`Cannot get dot product of ${a} and ${b}`);\n        }\n    }\n}\n\n/**\n * Cross product block.\n */\nexport class FlowGraphCrossBlock extends FlowGraphBinaryOperationBlock<Vector3, Vector3, Vector3> {\n    constructor(config?: IFlowGraphBlockConfiguration) {\n        super(RichTypeVector3, RichTypeVector3, RichTypeVector3, (a, b) => Vector3.Cross(a, b), FlowGraphBlockNames.Cross, config);\n    }\n}\n\n/**\n * 2D rotation block.\n */\nexport class FlowGraphRotate2DBlock extends FlowGraphBinaryOperationBlock<Vector2, number, Vector2> {\n    constructor(config?: IFlowGraphBlockConfiguration) {","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/FlowGraph/Blocks/Data/Math/flowGraphVectorMathBlocks.pure.ts#L144-L180","documentation":"The Dot Product block's _polymorphicDot computes .dot() only for Vector2, Vector3, Vector4 and Quaternion operand types; any other operand kind (scalar, boolean, Matrix, undefined) reaches the default case and throws 'Cannot get dot product of ...'. Both operands must be vector-like values of compatible dimensions.","triggerScenarios":"Executing FlowGraphDotBlock with a scalar (number/FlowGraphInteger), boolean, or Matrix on either input port; also feeding two vectors of differing dimension where the engine's dot() cannot reconcile them (cast as Vector3 internally).","commonSituations":"Wiring a numeric output (e.g. from a previous dot or length computation) back into a Dot block instead of a vector; mixing Vector2 and Vector3 inputs expecting automatic promotion; a graph where one vector input defaulted to a scalar after deserialization.","solutions":["Connect vector-typed values (Vector2/3/4 or Quaternion) to both inputs; promote scalars by constructing a vector first (e.g. new Vector3(s, s, s) block).","Match dimensions: convert Vector2 to Vector3 (append z) before dotting with a Vector3.","Fix the upstream wiring so both ports receive vector outputs."],"exampleFix":"// before: scalar into Dot block -> throws\ndotBlock.a.connect(scalarOutput); // number\n\n// after: vectors on both inputs\ndotBlock.a.connect(dirABlock.output); // Vector3\ndotBlock.b.connect(dirBBlock.output); // Vector3","handlingStrategy":"type-guard","validationCode":"// before Dot block runs\nfunction validDotInputs(a, b) {\n  const ok = (v) => v instanceof BABYLON.Vector2 || v instanceof BABYLON.Vector3 ||\n                    v instanceof BABYLON.Vector4 || v instanceof BABYLON.Quaternion;\n  return ok(a) && ok(b);\n}\nif (!validDotInputs(dotInputA, dotInputB)) throw new TypeError('Dot inputs must both be vector-like');","typeGuard":"function isVectorLike(v): v is BABYLON.Vector2 | BABYLON.Vector3 | BABYLON.Vector4 | BABYLON.Quaternion {\n  return v != null && typeof (v as any).dot === 'function';\n}","tryCatchPattern":"try {\n  result = dotBlock.evaluate(context);\n} catch (e) {\n  if (e.message.startsWith('Cannot get dot product of')) {\n    // promote scalars into matching vectors and retry\n    const va = vecFromScalar(a), vb = vecFromScalar(b);\n    result = va.dot(vb);\n  } else { throw e; }\n}","preventionTips":["Always dot vectors of the same dimension; add conversion blocks (Vector2->Vector3) when mixing.","Never feed the scalar result of a previous Dot/Length back into a Dot block.","Verify both input ports' connection sources after graph deserialization."],"tags":["babylonjs","flow-graph","vector-math","type-mismatch"],"backgroundTag":"non-vector-input","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}