hasura/graphql-engine · error · AggregateBooleanExpressionError

the operand type '{operand_type}' must be a scalar type

Error message

the operand type '{operand_type}' must be a scalar type

What it means

AggregateBooleanExpressionError::OperandTypeIsNotAScalarType: an aggregate boolean expression operand was declared with a type that is not a scalar (custom) type. Comparable operands in these expressions must reference scalar types so that comparison operators can be generated.

Source

Thrown at v3/crates/metadata-resolve/src/stages/aggregate_boolean_expressions/types.rs:137

impl ContextualError for NamedAggregateBooleanExpressionError {
    fn create_error_context(&self) -> Option<error_context::Context> {
        None
    }
}

#[derive(Debug, thiserror::Error)]
pub enum AggregateBooleanExpressionError {
    #[error("boolean expressions with aggregate operands are not supported")]
    AggregateBooleanExpressionsNotSupported,

    #[error("boolean expressions with aggregate operands do not support isNull comparisons")]
    IsNullComparisonsNotSupported,

    #[error("{0}")]
    GraphqlConfigError(#[from] GraphqlConfigError),

    #[error("the operand type '{operand_type}' must be a scalar type")]
    OperandTypeIsNotAScalarType {
        operand_type: Qualified<CustomTypeName>,
    },

    #[error("the operand type '{operand_type}' must be an object type")]
    OperandTypeIsNotAnObjectType {
        operand_type: Qualified<CustomTypeName>,
    },

    #[error("the aggregate expression '{aggregate_expression}' could not be found")]
    AggregateExpressionNotFound {
        aggregate_expression: Qualified<AggregateExpressionName>,
    },

    #[error(
        "the operand type '{operand_type}' does not match the operand type '{aggregate_operand}' from the aggregate expression '{aggregate_expression}'"
    )]
    AggregateOperandTypeMismatch {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Change the operand type to reference a declared scalar type
  2. Create a scalar type if the operand genuinely wraps a primitive value
  3. Double-check the qualified name: subgraph + name must resolve to a scalar

Example fix

# before
operand:
  type: app.User   # object type

# after
operand:
  type: app.UserStatus   # scalar type
Defensive patterns

Strategy: validation

Validate before calling

fn operand_is_scalar(metadata: &Metadata, operand: &Qualified<CustomTypeName>) -> bool {
    metadata.scalar_types.contains_key(operand)
}

Try / catch

if let AggregateBooleanExpressionError::OperandTypeIsNotAScalarType { operand_type } = err {
    eprintln!("{operand_type:?} must be declared as a scalar type");
}

Prevention

When it happens

Trigger: Pointing the operand of an aggregate boolean expression at an object type or another non-scalar Qualified<CustomTypeName>.

Common situations: Reusing an object type name for the operand, mixing up operand and target type references, metadata refactors that changed a scalar into an object type.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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