dgraph-io/dgraph · error

Fn not supported in preprocessFilter.

Error message

Fn %s not supported in preprocessFilter.

What it means

During preprocessing of a filter tree into a facet filter tree, only certain function types (facet comparators) are allowed. If a function name parsed from the query is not in the supported set, preprocessFilter rejects it with this error.

Solutions

  1. Use only supported facet functions (eq, le, ge, lt, gt) inside @facets.
  2. Move non-facet predicates (has, uid_in, type) out of @facets into the edge filter or func().
  3. Verify function availability for your Dgraph version.

Example fix

// before
friend @facets(uid_in(0x2))
// after
friend filter uid_in(0x2) { @facets(eq(name, "x")) }
Defensive patterns

Strategy: validation

Validate before calling

const preprocessableFns = new Set(["eq","le","ge","lt","gt"]);
function checkFacetFns(query) {
  for (const m of query.matchAll(/@facets\((\w+)/g)) {
    if (!preprocessableFns.has(m[1])) throw new Error(`Fn not allowed in preprocessFilter: ${m[1]}`);
  }
}

Try / catch

try {
  return await txn.query(query);
} catch (e) {
  if (/not supported in preprocessFilter/.test(String(e))) {
    // move the offending predicate out of @facets and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Using a function like uid_in, has, type(), or an unknown name inside an @facets filter, so the switch on fnType hits its default branch.

Common situations: Putting UID or scalar-predicate functions in facet filters; typos such as @facets(geq(x,1)); version drift where a function exists in newer Dgraph but not in the deployed one.

Related errors


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

Appendix: source

Thrown at worker/task.go:2466

			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
				}
				ftree.function.typesToVal[typeID] = cv
			}
		case standardFn:
			argTokens, aerr := tok.GetTermTokens(tree.Func.Args)
			if aerr != nil { // query error ; stop processing.
				return nil, aerr
			}
			sort.Strings(argTokens)
			ftree.function.tokens = argTokens
		default:
			return nil, errors.Errorf("Fn %s not supported in preprocessFilter.", fname)
		}
		return ftree, nil
	}

	for _, c := range tree.Children {
		ftreec, err := preprocessFilter(c)
		if err != nil {
			return nil, err
		}
		ftree.children = append(ftree.children, ftreec)
	}

	numChild := len(tree.Children)
	switch ftree.op {
	case "not":
		if numChild != 1 {
			return nil, errors.Errorf("Expected 1 child for not but got %d.", numChild)
		}

View on GitHub (pinned to 759e242be6)