dgraph-io/dgraph · error

One argument expected in %s, but got %d.

Error message

One argument expected in %s, but got %d.

What it means

Facet functions in Dgraph take exactly one argument (the facet value to compare). During parsing/preprocessing of a facet filter tree, the number of function arguments is validated; anything other than 1 triggers this error naming the function type and the actual count.

Source

Thrown at worker/task.go:2437

// commonTypeIDs is list of type ids which are more common. In preprocessFilter() we keep converted
// values for these typeIDs at every function node.
var commonTypeIDs = [...]types.TypeID{types.StringID, types.IntID, types.FloatID,
	types.DateTimeID, types.BoolID, types.DefaultID}

func preprocessFilter(tree *pb.FilterTree) (*facetsTree, error) {
	if tree == nil {
		return nil, nil
	}
	ftree := &facetsTree{}
	ftree.op = strings.ToLower(tree.Op)
	if tree.Func != nil {
		ftree.function = &facetsFunc{}
		ftree.function.key = tree.Func.Key
		ftree.function.args = tree.Func.Args

		fnType, fname := parseFuncTypeHelper(tree.Func.Name)
		if len(tree.Func.Args) != 1 {
			return nil, errors.Errorf("One argument expected in %s, but got %d.",
				fname, len(tree.Func.Args))
		}

		ftree.function.name = fname
		ftree.function.fnType = fnType

		switch fnType {
		case compareAttrFn:
			ftree.function.val = types.Val{Tid: types.StringID, Value: []byte(tree.Func.Args[0])}
			ftree.function.typesToVal = make(map[types.TypeID]types.Val, len(commonTypeIDs))
			for _, typeID := range commonTypeIDs {
				// TODO: if conversion is not possible we are not putting anything to map. In
				// applyFacetsTree we check if entry for a type is not present, we try to convert
				// it. This double conversion can be avoided.
				cv, err := types.Convert(ftree.function.val, typeID)
				if err != nil {
					continue
				}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Pass exactly one argument to the facet function, e.g. @facets(eq(name, "alice")).
  2. If a range is needed, compose two facet filters (ge and le) instead of passing two args to one fn.
  3. Note: `between` is not a valid facet-filter function; use ge/lt combinations.

Example fix

// before
friend @facets(between(score, 1, 10))
// after
friend @facets(ge(score, 1)) @facets(le(score, 10))
Defensive patterns

Strategy: validation

Validate before calling

function validateFacetFnArgs(query) {
  for (const m of query.matchAll(/@facets\(\w+\(([^)]*)\)/g)) {
    const argc = m[1].split(",").filter(s => s.trim() !== "").length;
    if (argc !== 1) throw new Error(`Facet fn needs exactly 1 arg, got ${argc}: @facets(${m[0]})`);
  }
}

Try / catch

try {
  return await txn.query(query);
} catch (e) {
  if (/One argument expected/.test(String(e))) {
    // surface the malformed facet expression to the caller
  }
  throw e;
}

Prevention

When it happens

Trigger: Writing @facets(eq(score, 1, 2)) or @facets(gt(weight)) — any facet function call with zero or two-plus arguments inside a facet filter.

Common situations: Misreading between(a,b) as usable in facets (between is not a one-arg facet fn); adding a comparison constant plus default value; copy-paste from regular filter syntax.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/8a3999e7e042a53d. Report an issue: GitHub.