{"record":{"id":"1c2b2a814f3549f0","repo":"dgraph-io/dgraph","slug":"invalid-types-v-v-for-func-s","errorCode":null,"errorMessage":"invalid types %v, %v for func %s","messagePattern":"invalid types (.+?), (.+?) for func (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"query/aggregator.go","lineNumber":647,"sourceCode":"func getValType(v *types.Val) valType {\n\tvar vBase valType\n\tswitch v.Tid {\n\tcase types.IntID:\n\t\tvBase = INT\n\tcase types.FloatID:\n\t\tvBase = FLOAT\n\tcase types.VFloatID:\n\t\tvBase = VFLOAT\n\tcase types.BigFloatID:\n\t\tvBase = BIGFLOAT\n\tdefault:\n\t\tvBase = DEFAULT\n\t}\n\treturn vBase\n}\n\nfunc invalidTypeError(left, right valType, funcName string) error {\n\treturn errors.Errorf(\"invalid types %v, %v for func %s\", left, right, funcName)\n}\n\n// matchType(left, right) will make sure that the left and right type\n// arguments agree, and otherwise convert left/right to an appropriate\n// type in some cases where it can.\n// matchType is invoked right before evaluating either a unary or binary\n// function indicated by ag.name. If evaluating a unary function, then\n// right is actually the single argument type, and left is actually the\n// resulting type. For invoking a binary function then left and right\n// of course play the role of being the left/right types (as expected).\nfunc (ag *aggregator) matchType(left, right *types.Val) error {\n\tleftType := getValType(left)\n\trightType := getValType(right)\n\n\tif rightType == VFLOAT {\n\t\tif _, ok := opsAllowingVectorsOnRight[ag.name]; !ok {\n\t\t\treturn invalidTypeError(leftType, rightType, ag.name)\n\t\t}","sourceCodeStart":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/query/aggregator.go#L629-L665","documentation":"invalidTypeError is the shared error constructor used by binary math aggregators (mul, div, dot) and matchType when the left and right operand types cannot be reconciled for the given function. matchType attempts to coerce operands to a common type (int/float/bigfloat); when both operands are incompatible for the function, this error reports both type IDs and the function name.","triggerScenarios":"Binary math between incompatible operands, e.g. adding/dividing/multiplying a string by a number, a bool by a float, or a dateTime by an int in math expressions; also division involving non-numeric typed values where no valid vBase can be computed.","commonSituations":"Mixing a string predicate with a numeric literal; comparing datetime arithmetic wrongly; schema drift making one side of the expression a different type; using uid variables inside arithmetic.","solutions":["Ensure both operands of the binary math function are numeric (int/float)","Check the schema types of both predicates involved","Cast datetime values via since() to floats before arithmetic","Rewrite the expression so string/bool values are not part of numeric math"],"exampleFix":"// before: dividing a string by a number\n\"math div(total_str, 2)\"\n// after: numeric predicate\n\"math div(total, 2)\"","handlingStrategy":"type-guard","validationCode":"function bothNumeric(t1, t2) {\n  const nums = ['int','float'];\n  return nums.includes(t1) && nums.includes(t2);\n}","typeGuard":"function isNumericValue(v) { return typeof v === 'number' && Number.isFinite(v); }","tryCatchPattern":"try {\n  r = await txn.query(q);\n} catch (e) {\n  if (String(e).includes('invalid types') ) {\n    console.error('Binary math operand type mismatch:', e.message);\n  }\n  throw e;\n}","preventionTips":["Verify both operands of binary math are numeric in schema","Convert datetime via since() before arithmetic","Never mix uid/string variables into numeric expressions","Test mixed-type queries during schema migrations"],"tags":["dgraph","query","binary-function","type-mismatch"],"backgroundTag":"math-function-invalid-type","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}