{"record":{"id":"80f7e3f290101b06","repo":"dgraph-io/dgraph","slug":"leaf-predicate-v-must-be-a-scalar","errorCode":null,"errorMessage":"Leaf predicate:'%v' must be a scalar.","messagePattern":"Leaf predicate:'(.+?)' must be a scalar\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"query/query.go","lineNumber":429,"sourceCode":"\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc isEmptyIneqFnWithVar(sg *SubGraph) bool {\n\treturn sg.SrcFunc != nil && isInequalityFn(sg.SrcFunc.Name) && len(sg.SrcFunc.Args) == 0 &&\n\t\tlen(sg.Params.NeedsVar) > 0\n}\n\n// convert from task.Val to types.Value, based on schema appropriate type\n// is already set in api.Value\nfunc convertWithBestEffort(tv *pb.TaskValue, attr string) (types.Val, error) {\n\t// value would be in binary format with appropriate type\n\ttid := types.TypeID(tv.ValType)\n\tif !tid.IsScalar() {\n\t\treturn types.Val{}, errors.Errorf(\"Leaf predicate:'%v' must be a scalar.\", attr)\n\t}\n\n\t// creates appropriate type from binary format\n\tsv, err := types.Convert(types.Val{Tid: types.BinaryID, Value: tv.Val}, tid)\n\tif err != nil {\n\t\t// This can happen when a mutation ingests corrupt data into the database.\n\t\treturn types.Val{}, errors.Wrapf(err, \"error interpreting appropriate type for %v\", attr)\n\t}\n\treturn sv, nil\n}\n\nfunc mathCopy(dst *mathTree, src *dql.MathTree) error {\n\t// Either we'll have an operation specified, or the function specified.\n\tdst.Const = src.Const\n\tdst.Fn = src.Fn\n\tdst.Val = src.Val\n\tdst.Var = src.Var\n","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/query/query.go#L411-L447","documentation":"convertWithBestEffort converts an internal task value to a typed value using the schema type. If the value's type ID is not a scalar (i.e. it is a UID/list-of-UID), the conversion cannot proceed and this error is thrown, because only scalar predicates can be converted to a plain value here.","triggerScenarios":"Calling convertWithBestEffort with a TaskValue whose ValType is a UID type — e.g. preTraverse reading a node-predicate value as if it were scalar, aggregateGroup aggregating a non-scalar predicate, rdfForValueList on uid lists.","commonSituations":"Aggregating or traversing over a predicate that stores UIDs (edges) but treating it as a leaf/scalar in math/aggregation code; schema drift where a predicate changed from scalar to uid.","solutions":["Ensure the predicate being aggregated/read is a scalar type in the schema","Use the uid-typed predicate only in edge traversal, not in value conversion paths","Fix corrupt/inconsistent schema so the value type matches usage"],"exampleFix":"// before\nval, err := convertWithBestEffort(tv, \"friend\") // friend is uid predicate\n// after\nval, err := convertWithBestEffort(tv, \"name\") // scalar predicate, e.g. string","handlingStrategy":"type-guard","validationCode":"// Go: check schema type is scalar before treating value as scalar leaf\nvar sch types.Schema\nif err := client.CheckSchema(ctx, pred, &sch); err == nil && !types.TypeID(sch.Type).IsScalar() {\n    return fmt.Errorf(\"predicate %s is not scalar; cannot aggregate/convert\", pred)\n}","typeGuard":"func isScalarValue(tv *pb.TaskValue) bool {\n    return types.TypeID(tv.ValType).IsScalar()\n}","tryCatchPattern":"val, err := convertWithBestEffort(tv, attr)\nif err != nil && strings.Contains(err.Error(), \"must be a scalar\") {\n    // treat as edge/uid predicate: handle as UID list instead\n    return handleUidPredicate(tv, attr)\n}","preventionTips":["Verify schema types before writing value-conversion code","Only pass scalar predicates (string, int, float, bool, datetime) to aggregation","Guard against schema drift between environments"],"tags":["dgraph","types","scalar","value-conversion"],"backgroundTag":"non-scalar-predicate-value-conversion","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}