{"record":{"id":"87291bb72140df04","repo":"apache/cassandra","slug":"cannot-create-aggregate-s-without-initcond-beca","errorCode":null,"errorMessage":"Cannot create aggregate '%s' without INITCOND because state function %s does not accept 'null' arguments","messagePattern":"Cannot create aggregate '(.+?)' without INITCOND because state function (.+?) does not accept 'null' arguments","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java","lineNumber":202,"sourceCode":"                }\n                catch (MarshalException e)\n                {\n                    throw ire(\"Invalid value for INITCOND of type %s\", stateType.asCQL3Type());\n                }\n            }\n\n            // Converts initcond to a CQL literal and parse it back to avoid another CASSANDRA-11064\n            String initialValueString = stateType.asCQL3Type().toCQLLiteral(initialValue);\n            if (!Objects.equal(initialValue, stateType.asCQL3Type().fromCQLLiteral(initialValueString)))\n                throw new AssertionError(String.format(\"CQL literal '%s' (from type %s) parsed with a different value\", initialValueString, stateType.asCQL3Type()));\n\n            if (Constants.NULL_LITERAL != rawInitialValue && isNullOrEmpty(stateType, initialValue))\n                throw ire(\"INITCOND must not be empty for all types except TEXT, ASCII, BLOB\");\n        }\n\n        if (!((UDFunction) stateFunction).isCalledOnNullInput() && null == initialValue)\n        {\n            throw ire(\"Cannot create aggregate '%s' without INITCOND because state function %s does not accept 'null' arguments\",\n                      aggregateName,\n                      stateFunctionName);\n        }\n\n        /*\n         * Create or replace\n         */\n\n        UDAggregate aggregate =\n            new UDAggregate(new FunctionName(keyspaceName, aggregateName),\n                            argumentTypes,\n                            returnType,\n                            (ScalarFunction) stateFunction,\n                            (ScalarFunction) finalFunction,\n                            initialValue);\n\n        UserFunction existingAggregate = keyspace.userFunctions.find(aggregate.name(), argumentTypes).orElse(null);\n        if (null != existingAggregate)","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java#L184-L220","documentation":"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.","triggerScenarios":"CREATE AGGREGATE with a state function created with RETURNS NULL ON NULL INPUT and no INITCOND clause.","commonSituations":"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.","solutions":["Add an INITCOND clause with the initial state value.","Recreate the state function with CALLED ON NULL INPUT so null initial state is legal.","Both together: CALLED ON NULL INPUT plus a meaningful null-handling state function and no INITCOND."],"exampleFix":"// before\nCREATE AGGREGATE ks.sum(int) SFUNC add_one STYPE int; -- add_one is RETURNS NULL ON NULL INPUT\n// after\nCREATE AGGREGATE ks.sum(int) SFUNC add_one STYPE int INITCOND 0;","handlingStrategy":"validation","validationCode":"if (!stateFunction.isCalledOnNullInput() && rawInitialValue == null)\n    throw new IllegalArgumentException(\"INITCOND required: state function \" + stateFn + \" is RETURNS NULL ON NULL INPUT\");","typeGuard":null,"tryCatchPattern":"try { session.execute(ddl); }\ncatch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"without INITCOND\")) { /* add INITCOND or recreate SFUNC as CALLED ON NULL INPUT */ }\n    else throw e;\n}","preventionTips":["Create state functions with CALLED ON NULL INPUT when they will be used in aggregates.","Always pair non-null-tolerant state functions with an explicit INITCOND."],"tags":["cql","initcond","user-defined-function"],"backgroundTag":"missing-required-argument","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}