hasura/graphql-engine · error · InternalDeveloperError

A field ({field_name}) with an AggregatableField annotation

Error message

A field ({field_name}) with an AggregatableField annotation was found on a scalar-typed ({aggregate_operand_type}) operand's selection set

What it means

A field carrying an AggregatableField annotation appeared inside the selection set of an aggregation operand that is scalar-typed. Scalar operands have no subfields, so an aggregatable field there is a contradiction detected during IR validation.

Source

Thrown at v3/crates/graphql/ir/src/error.rs:231

    #[error(
        "Argument mapping not found for the argument {argument_name:} while executing the relationship {relationship_name:}"
    )]
    ArgumentMappingNotFoundForRelationship {
        relationship_name: RelationshipName,
        argument_name: ArgumentName,
    },

    #[error(
        "The aggregation function {aggregation_function} operating over the {aggregate_operand_type} type is missing a data connector mapping for {data_connector_name}"
    )]
    DataConnectorAggregationFunctionNotFound {
        aggregate_operand_type: QualifiedTypeName,
        aggregation_function: AggregationFunctionName,
        data_connector_name: Qualified<DataConnectorName>,
    },

    #[error(
        "A field ({field_name}) with an AggregatableField annotation was found on a scalar-typed ({aggregate_operand_type}) operand's selection set"
    )]
    AggregatableFieldFoundOnScalarTypedOperand {
        field_name: FieldName,
        aggregate_operand_type: QualifiedTypeName,
    },

    #[error(
        "The aggregation function {aggregation_function} was used on the model object type and not on a model field. Aggregation functions operate on columns, not rows"
    )]
    ColumnAggregationFunctionUsedOnModelObjectType {
        aggregate_operand_type: QualifiedTypeName,
        aggregation_function: AggregationFunctionName,
    },

    #[error("{0}")]
    PlanInternalDeveloperError(plan::InternalDeveloperError),
}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Restructure the aggregate selection so aggregatable fields only appear under object/array-typed operands
  2. Use the standard client-generated aggregate query shape
  3. Validate the aggregate query against the schema before execution
Defensive patterns

Strategy: validation

Validate before calling

// Only nest aggregatable fields under object-typed operands
if (isScalarType(operandType) && selectionHasFields(sel)) throw new Error('bad aggregate shape');

Type guard

const isValidAggregateSelection = (operandType, sel) =>
  !isScalarType(operandType) || sel.selectionSet === undefined;

Try / catch

// Catch and restructure the aggregate selection to the documented shape

Prevention

When it happens

Trigger: Selecting aggregatable subfields under a scalar operand in an _aggregate query; malformed aggregate selections generated by hand or by buggy query builders; metadata marking a scalar operand as having aggregatable fields.

Common situations: Hand-written aggregate queries with wrong nesting; codegen producing deeply nested aggregate fragments incorrectly.

Related errors


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