apache/cassandra · error · InvalidRequestException

Cannot create aggregate

Error message

Cannot create aggregate '%s' without INITCOND because state function %s does not accept 'null' arguments

What it means

Thrown when no INITCOND is given but the aggregate's state function is declared RETURNS NULL ON NULL INPUT (not CALLED ON NULL INPUT). With such a state function, a null initial state would make every aggregation return null, so Cassandra requires an explicit INITCOND.

Solutions

  1. Add an INITCOND clause with the initial state value.
  2. Recreate the state function with CALLED ON NULL INPUT so null initial state is legal.
  3. Both together: CALLED ON NULL INPUT plus a meaningful null-handling state function and no INITCOND.

Example fix

// before
CREATE AGGREGATE ks.sum(int) SFUNC add_one STYPE int; -- add_one is RETURNS NULL ON NULL INPUT
// after
CREATE AGGREGATE ks.sum(int) SFUNC add_one STYPE int INITCOND 0;
Defensive patterns

Strategy: validation

Validate before calling

if (!stateFunction.isCalledOnNullInput() && rawInitialValue == null)
    throw new IllegalArgumentException("INITCOND required: state function " + stateFn + " is RETURNS NULL ON NULL INPUT");

Try / catch

try { session.execute(ddl); }
catch (InvalidRequestException e) {
    if (e.getMessage().contains("without INITCOND")) { /* add INITCOND or recreate SFUNC as CALLED ON NULL INPUT */ }
    else throw e;
}

Prevention

When it happens

Trigger: CREATE AGGREGATE with a state function created with RETURNS NULL ON NULL INPUT and no INITCOND clause.

Common situations: Reusing a scalar UDF written for normal expression evaluation (defaulting to RETURNS NULL ON NULL INPUT) as an aggregate state function; forgetting INITCOND after dropping it during a migration.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

                }
                catch (MarshalException e)
                {
                    throw ire("Invalid value for INITCOND of type %s", stateType.asCQL3Type());
                }
            }

            // Converts initcond to a CQL literal and parse it back to avoid another CASSANDRA-11064
            String initialValueString = stateType.asCQL3Type().toCQLLiteral(initialValue);
            if (!Objects.equal(initialValue, stateType.asCQL3Type().fromCQLLiteral(initialValueString)))
                throw new AssertionError(String.format("CQL literal '%s' (from type %s) parsed with a different value", initialValueString, stateType.asCQL3Type()));

            if (Constants.NULL_LITERAL != rawInitialValue && isNullOrEmpty(stateType, initialValue))
                throw ire("INITCOND must not be empty for all types except TEXT, ASCII, BLOB");
        }

        if (!((UDFunction) stateFunction).isCalledOnNullInput() && null == initialValue)
        {
            throw ire("Cannot create aggregate '%s' without INITCOND because state function %s does not accept 'null' arguments",
                      aggregateName,
                      stateFunctionName);
        }

        /*
         * 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)

View on GitHub (pinned to 88fd0f6a0e)