hasura/graphql-engine · error · AggregateExpressionError

the following aggregate expression is defined more than once

Error message

the following aggregate expression is defined more than once: {name}

What it means

Two aggregate expression definitions in the metadata share the same qualified name, so the resolver cannot unambiguously produce an aggregate expression for that name. Duplicate definitions must be removed or renamed.

Source

Thrown at v3/crates/metadata-resolve/src/stages/aggregates/types.rs:101

    pub count_distinct_field_name: ast::Name,

    pub select_output_type_name: ast::TypeName,
}

#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)]
pub enum AggregateExpressionIssue {
    #[error(
        "the aggregate expression {name} defines a graphql section but it will not appear in the GraphQL API unless {config_name} is also configured in the GraphqlConfig"
    )]
    ConfigMissingFromGraphQlConfig {
        name: Qualified<AggregateExpressionName>,
        config_name: String,
    },
}

#[derive(Debug, thiserror::Error)]
pub enum AggregateExpressionError {
    #[error("the following aggregate expression is defined more than once: {name}")]
    DuplicateAggregateExpressionDefinition {
        name: Qualified<AggregateExpressionName>,
    },

    #[error(
        "the name used by {config_name} from the GraphqlConfig conflicts with the aggregatable field name {aggregatable_field_name} in the aggregate expression {name}"
    )]
    AggregatableFieldNameConflict {
        name: Qualified<AggregateExpressionName>,
        config_name: String,
        aggregatable_field_name: FieldName,
    },

    #[error(
        "the name used by {config_name} from the GraphqlConfig conflicts with the aggregation function name {function_name} in the aggregate expression {name}"
    )]
    AggregationFunctionNameConflict {
        name: Qualified<AggregateExpressionName>,

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Search the metadata for the duplicate name shown in the error and delete or rename one definition.
  2. Check for accidental double-inclusion of the same metadata file/document in the build.
  3. Ensure each subgraph defines its expressions with unique names if both must coexist.

Example fix

# before
aggregate_expressions:
  - name: avg_rating   # file A
  - name: avg_rating   # file B (duplicate)
# after
aggregate_expressions:
  - name: avg_rating   # file A
  - name: avg_rating_v2 # file B, renamed
Defensive patterns

Strategy: try-catch

Validate before calling

let mut seen = HashSet::new();
for expr in &metadata.aggregate_expressions {
    assert!(seen.insert(expr.name.clone()),
        "duplicate aggregate expression definition: {}", expr.name);
}

Try / catch

match resolve_aggregates(&ctx) {
    Err(errors) => {
        for e in &errors {
            if let AggregateExpressionError::DuplicateAggregateExpressionDefinition { name } = e {
                eprintln!("duplicate aggregate expression: {} — remove or rename one definition", name);
            }
        }
    }
    Ok(v) => { /* ... */ }
}

Prevention

When it happens

Trigger: Declaring the same Qualified<AggregateExpressionName> (same subgraph + name) in two aggregate expression files, or re-including the same metadata document twice during composition.

Common situations: Copy-pasting an aggregate expression YAML and forgetting to rename it; merging metadata crates that both define the expression; accidental double-application of metadata documents in a build pipeline.

Related errors


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