{"record":{"id":"b143404d6fe593f1","repo":"dgraph-io/dgraph","slug":"expected-after-math","errorCode":null,"errorMessage":"Expected ( after math","messagePattern":"Expected \\( after math","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dql/math.go","lineNumber":164,"sourceCode":"}\n\nfunc isMathFunc(f string) bool {\n\t// While adding an op, also add it to the corresponding function type.\n\treturn f == \"*\" || f == \"%\" || f == \"+\" || f == \"-\" || f == \"/\" ||\n\t\tf == \"exp\" || f == \"ln\" || f == \"cond\" ||\n\t\tf == \"<\" || f == \">\" || f == \">=\" || f == \"<=\" ||\n\t\tf == \"==\" || f == \"!=\" ||\n\t\tf == \"min\" || f == \"max\" || f == \"sqrt\" ||\n\t\tf == \"pow\" || f == \"logbase\" || f == \"floor\" || f == \"ceil\" ||\n\t\tf == \"since\" || f == \"dot\"\n}\n\nfunc parseMathFunc(gq *GraphQuery, it *lex.ItemIterator, again bool) (*MathTree, bool, error) {\n\tif !again {\n\t\tit.Next()\n\t\titem := it.Item()\n\t\tif item.Typ != itemLeftRound {\n\t\t\treturn nil, false, errors.Errorf(\"Expected ( after math\")\n\t\t}\n\t}\n\n\t// opStack is used to collect the operators in right order.\n\topStack := new(mathTreeStack)\n\topStack.push(&MathTree{Fn: \"(\"}) // Push ( onto operator stack.\n\t// valueStack is used to collect the values.\n\tvalueStack := new(mathTreeStack)\n\nloop:\n\tfor it.Next() {\n\t\titem := it.Item()\n\t\tlval := strings.ToLower(item.Val)\n\t\tswitch {\n\t\tcase isMathFunc(lval):\n\t\t\top := lval\n\t\t\tit.Prev()\n\t\t\tlastItem := it.Item()","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/dql/math.go#L146-L182","documentation":"The DQL parser found the 'math' keyword but the next lexer item was not '('. parseMathFunc requires math to be immediately followed by an opening parenthesis; anything else (space-separated token, brace, comma) fails parsing.","triggerScenarios":"Writing math without parentheses: `u as math a + b`, a line break/token between math and (, or using math as a value name without invoking it, e.g. `math(a)` misspelled as `math (a)` is fine but `math.a` or `math:` fails.","commonSituations":"Typos in query blocks; pasting SQL-style expressions into DQL; forgetting the parentheses when converting a plain aggregation to math; editing tools that split tokens.","solutions":["Wrap the expression in parentheses directly after math: math(a + b).","Remove any characters between 'math' and '('.","Check the aggregation block syntax: `total as math(count + 1)` inside a query.","Validate the query with a minimal example first, then add complexity."],"exampleFix":"// before\ntotal as math count + 1\n// after\ntotal as math(count + 1)","handlingStrategy":"validation","validationCode":"// 'math' must be immediately followed by '('\nconst re = /\\bmath\\s*\\(/;\nif (!re.test('total as math(count + 1)')) {\n  throw new Error('math must be invoked as math(expression)');\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await dgraph.query(query);\n} catch (err) {\n  if (/Expected \\( after math/.test(String(err))) {\n    throw new Error('Syntax: wrap math expression in parentheses, e.g. math(a + b)');\n  }\n  throw err;\n}","preventionTips":["Always invoke math as math(...) — never as a bare keyword","Beware editors/tools inserting whitespace or tokens between math and (","Copy valid DQL math examples rather than adapting SQL syntax","Run queries through a parser/validator before production use"],"tags":["dql","dgraph","syntax","math-parser"],"backgroundTag":"invalid-query-syntax","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}