apache/cassandra · error · InvalidRequestException

Aggregate ' ' cannot replace a function

Error message

Aggregate '%s' cannot replace a function

What it means

Thrown when creating an aggregate whose signature (name + argument types) collides with an existing scalar FUNCTION in the same keyspace. Functions and aggregates share one namespace per signature, so an aggregate cannot replace a plain function.

Solutions

  1. DROP FUNCTION ks.f (with the same argument types) before creating the aggregate.
  2. Choose a different name for the aggregate.
  3. Note that OR REPLACE does not help here — replacing a function with an aggregate is never permitted.

Example fix

// before
CREATE AGGREGATE ks.f(int) SFUNC s STYPE int; -- ks.f(int) is a scalar function
// after
DROP FUNCTION ks.f(int);
CREATE AGGREGATE ks.f(int) SFUNC s STYPE int;
Defensive patterns

Strategy: validation

Validate before calling

var existing = keyspace.userFunctions.find(fnName, argTypes);
if (existing.isPresent() && !existing.get().isAggregate())
    throw new IllegalStateException("A function named " + fnName + " already exists; drop it before creating the aggregate");

Try / catch

try { session.execute(ddl); }
catch (InvalidRequestException e) {
    if (e.getMessage().contains("cannot replace a function")) { /* DROP FUNCTION then retry */ }
    else throw e;
}

Prevention

When it happens

Trigger: CREATE AGGREGATE ks.f(...) where a scalar function ks.f with identical argument types already exists (without OR REPLACE semantics applying, which would still be rejected because the existing object is not an aggregate).

Common situations: Name reuse between UDF and UDA; scripted DDL that created the object first as a function; refactoring a function into an aggregate without dropping the original.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java:223

        }

        /*
         * Create or replace
         */

        UDAggregate aggregate =
            new UDAggregate(new FunctionName(keyspaceName, aggregateName),
                            argumentTypes,
                            returnType,
                            (ScalarFunction) stateFunction,
                            (ScalarFunction) finalFunction,
                            initialValue);

        UserFunction existingAggregate = keyspace.userFunctions.find(aggregate.name(), argumentTypes).orElse(null);
        if (null != existingAggregate)
        {
            if (!existingAggregate.isAggregate())
                throw ire("Aggregate '%s' cannot replace a function", aggregateName);

            if (ifNotExists)
                return schema;

            if (!orReplace)
                throw ire("Aggregate '%s' already exists", aggregateName);

            if (!returnType.isCompatibleWith(existingAggregate.returnType()))
            {
                throw ire("Cannot replace aggregate '%s', the new return type %s isn't compatible with the return type %s of existing function",
                          aggregateName,
                          returnType.asCQL3Type(),
                          existingAggregate.returnType().asCQL3Type());
            }
        }

        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.userFunctions.withAddedOrUpdated(aggregate)));
    }

View on GitHub (pinned to 88fd0f6a0e)