hasura/graphql-engine · error · TypePredicateError

Nested predicate used in type '{type_name:}'

Error message

Nested predicate used in type '{type_name:}'

What it means

A predicate for the given type contained a nested predicate where one was not allowed. The boolean expression type in question does not support nested sub-predicates at that position, so the resolver rejects the structure outright.

Source

Thrown at v3/crates/metadata-resolve/src/types/error.rs:471

        field_name: Spanned<FieldName>,
        field_type: QualifiedTypeReference,
        type_name: Qualified<CustomTypeName>,
    },
    #[error(
        "field '{field_name}' of type '{type_name}' used in a field comparison is a predicate type and therefore cannot be compared to a single value"
    )]
    UnsupportedFieldComparisonToPredicateType {
        field_name: Spanned<FieldName>,
        field_type: QualifiedTypeReference,
        type_name: Qualified<CustomTypeName>,
    },

    #[error("Invalid operator used in type '{type_name:}' predicate: '{operator_name:}'")]
    InvalidOperatorInTypePredicate {
        type_name: Qualified<CustomTypeName>,
        operator_name: Spanned<OperatorName>,
    },
    #[error("Nested predicate used in type '{type_name:}'")]
    NestedPredicateInTypePredicate {
        type_name: Qualified<CustomTypeName>,
    },
    #[error(
        "no boolean expression found for type '{type_name:}' This is required when filtering a nested field. Please ensure the model you are filtering has a filterExpressionType defined."
    )]
    NoBooleanExpressionFields {
        field_name: Spanned<FieldName>,
        type_name: Qualified<CustomTypeName>,
    },
    #[error(
        "relationship '{relationship_name}' is used in predicate but does not exist for type '{type_name}'"
    )]
    UnknownRelationshipInTypePredicate {
        relationship_name: Spanned<RelationshipName>,
        type_name: Qualified<CustomTypeName>,
    },
    #[error(

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Flatten the predicate: the value at that position should be a leaf comparison, not another predicate
  2. Extend the boolean expression type to support nested expressions if nesting is genuinely needed
  3. Validate filter payload shapes against the expression type schema before sending

Example fix

// before
{"field": "age", "operator": "_eq", "value": {"operator": "_gt", "value": 18}}
// after
{"field": "age", "operator": "_gt", "value": 18}
Defensive patterns

Strategy: validation

Validate before calling

// Validate predicate shape: leaf positions must hold values, not nested predicates
if is_leaf_position(&expr) && is_predicate(&expr.value) {
    return Err("nested predicate not allowed here".into());
}

Type guard

fn is_nested_predicate(v: &PredicateValue) -> bool {
    matches!(v, PredicateValue::Expression(_))
}

Try / catch

if let Err(TypePredicateError::NestedPredicateInTypePredicate { type_name }) = result {
    // flatten the predicate structure and retry
}

Prevention

When it happens

Trigger: Embedding a full predicate object inside a type predicate whose operator/field position only accepts scalar values or leaf expressions; deeply nested `_and`/`_or` structures beyond what the expression type models.

Common situations: Machine-generated filters that always wrap values in expression objects; converting flat filters to nested ones without updating the expression type; expression types that only define leaf operators.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/89f605da36c1bb66. Report an issue: GitHub.