apache/cassandra · error · InvalidRequestException
State function isn't a scalar function
Error message
State function %s isn't a scalar function
What it means
The state function resolved for the aggregate is itself an aggregate, not a scalar (non-aggregate) function. An aggregate's state function must be a plain user function; nesting aggregates is not allowed.
Solutions
- Point SFUNC at a scalar function with a matching signature (CREATE FUNCTION if missing)
- Drop/rename the conflicting aggregate so the name resolves to the scalar function
- Qualify with a different keyspace where the name refers to a scalar function
Example fix
// before CREATE FUNCTION ks.avg AS ... ; CREATE AGGREGATE ks.total(int) SFUNC avg ... // after CREATE FUNCTION ks.avg_state(int,int) ... CREATE AGGREGATE ks.total(int) SFUNC avg_state ...
Defensive patterns
Strategy: validation
Validate before calling
// verify the SFUNC resolves to a scalar function before CREATE AGGREGATE
Row f = session.execute("SELECT argument_types, return_type FROM system_schema.functions WHERE keyspace_name=? AND function_name=?", ks, sfunc).one();
if (f == null) throw new IllegalStateException("SFUNC not found: " + sfunc); Try / catch
try { session.execute(ddl); }
catch (InvalidRequestException e) { if (e.getMessage().contains("isn't a scalar function")) pickScalarFunctionFor(sfuncName); else throw e; } Prevention
- Name aggregates and functions distinctly to avoid signature collisions
- Query system_schema.functions/aggregates to confirm which object a name resolves to
- Never use an aggregate's name as the SFUNC of another aggregate
When it happens
Trigger: keyspace.userFunctions.find(stateFunctionName, stateFunctionArguments) returns a UserFunction whose isAggregate() is true, in CreateAggregateStatement.apply.
Common situations: Using an existing aggregate name as the SFUNC of a new aggregate; accidentally creating a function with the same signature as an aggregate earlier.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Aggregate name ' ' is invalid
- Ambiguous call to function
- Argument ' ' cannot be frozen; remove frozen<> modifier from
- Cannot alter user type
- Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/66906f3eefd32383.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java:141
/*
* Resolve the state function
*/
List<AbstractType<?>> argumentTypes =
rawArgumentTypes.stream()
.map(t -> t.prepare(keyspaceName, keyspace.types).getType().udfType())
.collect(toList());
AbstractType<?> stateType = rawStateType.prepare(keyspaceName, keyspace.types).getType().udfType();
List<AbstractType<?>> stateFunctionArguments = Lists.newArrayList(concat(singleton(stateType), argumentTypes));
UserFunction stateFunction =
keyspace.userFunctions
.find(stateFunctionName, stateFunctionArguments)
.orElseThrow(() -> ire("State function %s doesn't exist", stateFunctionString()));
if (stateFunction.isAggregate())
throw ire("State function %s isn't a scalar function", stateFunctionString());
if (!stateFunction.returnType().equals(stateType))
{
throw ire("State function %s return type must be the same as the first argument type - check STYPE, argument and return types",
stateFunctionString());
}
/*
* Resolve the final function and return type
*/
UserFunction finalFunction = null;
AbstractType<?> returnType = stateFunction.returnType();
if (null != finalFunctionName)
{
finalFunction = keyspace.userFunctions.find(finalFunctionName, singletonList(stateType)).orElse(null);
if (null == finalFunction)View on GitHub (pinned to 88fd0f6a0e)