apache/cassandra · error · InvalidRequestException

'DROP AGGREGATE ' matches multiple function definitions…

Error message

'DROP AGGREGATE %s' matches multiple function definitions; specify the argument types by issuing a statement like 'DROP AGGREGATE %s (type, type, ...)'. You can use cqlsh 'DESCRIBE AGGREGATE %s' command to find all overloads

What it means

The keyspace contains multiple overloads of the aggregate name, and the DROP AGGREGATE statement did not specify argument types, so the target is ambiguous. Cassandra refuses to guess which overload to drop.

Solutions

  1. Drop with explicit argument types: DROP AGGREGATE ks.agg (type1, type2);
  2. Run 'DESCRIBE AGGREGATE ks.agg' in cqlsh to list all overloads and their signatures
  3. Add IF EXISTS if a matching-signature drop is optional

Example fix

// before
DROP AGGREGATE sales.avg_sale;
// after
DROP AGGREGATE sales.avg_sale (int);
Defensive patterns

Strategy: validation

Validate before calling

const rows = await session.execute("SELECT argument_types, count(*) FROM system_schema.aggregates WHERE keyspace_name=? AND aggregate_name=? GROUP BY argument_types", [ks, name]); if (rows.rowLength > 1) throw new Error('Ambiguous: specify argument types');

Try / catch

try { session.execute(ddl); } catch (e) { if (e instanceof InvalidQueryError && /matches multiple function definitions/.test(e.message)) { /* re-issue with explicit (type, ...) list */ } else throw e; }

Prevention

When it happens

Trigger: DROP AGGREGATE agg (no parenthesized type list) when two or more UDAs named agg with different signatures exist in the keyspace.

Common situations: Overloaded aggregates created with different argument types over time; migration scripts that drop by name only; cqlsh DESCRIBE not consulted before dropping.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/6bfa812ba1911025. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/DropAggregateStatement.java:98

        String name =
            argumentsSpeficied
          ? format("%s.%s(%s)", keyspaceName, aggregateName, join(", ", transform(arguments, CQL3Type.Raw::toString)))
          : format("%s.%s", keyspaceName, aggregateName);

        Keyspaces schema = metadata.schema.getKeyspaces();
        KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);
        if (null == keyspace)
        {
            if (ifExists)
                return schema;

            throw ire("Aggregate '%s' doesn't exist", name);
        }

        Collection<UserFunction> aggregates = keyspace.userFunctions.get(new FunctionName(keyspaceName, aggregateName));
        if (aggregates.size() > 1 && !argumentsSpeficied)
        {
            throw ire("'DROP AGGREGATE %s' matches multiple function definitions; " +
                      "specify the argument types by issuing a statement like " +
                      "'DROP AGGREGATE %s (type, type, ...)'. You can use cqlsh " +
                      "'DESCRIBE AGGREGATE %s' command to find all overloads",
                      aggregateName, aggregateName, aggregateName);
        }

        arguments.stream()
                 .filter(raw -> !raw.isImplicitlyFrozen() && raw.isFrozen())
                 .findFirst()
                 .ifPresent(t -> { throw ire("Argument '%s' cannot be frozen; remove frozen<> modifier from '%s'", t, t); });

        List<AbstractType<?>> argumentTypes = prepareArgumentTypes(keyspace.types);

        Predicate<UserFunction> filter = UserFunctions.Filter.UDA;
        if (argumentsSpeficied)
            filter = filter.and(f -> f.typesMatch(argumentTypes));

        UserFunction aggregate = aggregates.stream().filter(filter).findAny().orElse(null);

View on GitHub (pinned to 88fd0f6a0e)