{"record":{"id":"e598844cf2bde72e","repo":"apache/cassandra","slug":"state-function-s-return-type-must-be-the-same-as","errorCode":null,"errorMessage":"State function %s return type must be the same as the first argument type - check STYPE, argument and return types","messagePattern":"State function (.+?) return type must be the same as the first argument type - check STYPE, argument and return types","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java","lineNumber":145,"sourceCode":"\n        List<AbstractType<?>> argumentTypes =\n            rawArgumentTypes.stream()\n                            .map(t -> t.prepare(keyspaceName, keyspace.types).getType().udfType())\n                            .collect(toList());\n        AbstractType<?> stateType = rawStateType.prepare(keyspaceName, keyspace.types).getType().udfType();\n        List<AbstractType<?>> stateFunctionArguments = Lists.newArrayList(concat(singleton(stateType), argumentTypes));\n\n        UserFunction stateFunction =\n            keyspace.userFunctions\n                    .find(stateFunctionName, stateFunctionArguments)\n                    .orElseThrow(() -> ire(\"State function %s doesn't exist\", stateFunctionString()));\n\n        if (stateFunction.isAggregate())\n            throw ire(\"State function %s isn't a scalar function\", stateFunctionString());\n\n        if (!stateFunction.returnType().equals(stateType))\n        {\n            throw ire(\"State function %s return type must be the same as the first argument type - check STYPE, argument and return types\",\n                      stateFunctionString());\n        }\n\n        /*\n         * Resolve the final function and return type\n         */\n\n        UserFunction finalFunction = null;\n        AbstractType<?> returnType = stateFunction.returnType();\n\n        if (null != finalFunctionName)\n        {\n            finalFunction = keyspace.userFunctions.find(finalFunctionName, singletonList(stateType)).orElse(null);\n            if (null == finalFunction)\n                throw ire(\"Final function %s doesn't exist\", finalFunctionString());\n\n            if (finalFunction.isAggregate())\n                throw ire(\"Final function %s isn't a scalar function\", finalFunctionString());","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java#L127-L163","documentation":"The resolved state function's return type must equal the aggregate's STYPE (which is also the first argument type). A mismatch means the accumulator's type would be inconsistent, so the CREATE AGGREGATE is rejected.","triggerScenarios":"!stateFunction.returnType().equals(stateType) after resolving the state function in CreateAggregateStatement.apply.","commonSituations":"SFUNC returning a different type than declared STYPE (e.g. function returns bigint, STYPE int); changing STYPE after the function was written; copy-pasted aggregate templates.","solutions":["Align STYPE with the state function's declared return type","Alter the state function (recreate with RETURNS) to return the STYPE","Adjust the argument types so the first argument type matches the function's return"],"exampleFix":"// before\nCREATE AGGREGATE ks.sum(int) SFUNC addf ... -- addf RETURNS bigint\n// after\nCREATE AGGREGATE ks.sum(bigint) SFUNC addf ... -- STYPE matches addf return type","handlingStrategy":"validation","validationCode":"// compare SFUNC return type with STYPE before executing DDL\nRow f = session.execute(\"SELECT return_type FROM system_schema.functions WHERE keyspace_name=? AND function_name=?\", ks, sfunc).one();\nif (f != null && !f.getString(\"return_type\").equalsIgnoreCase(stype))\n    throw new IllegalStateException(\"SFUNC return type \" + f.getString(\"return_type\") + \" != STYPE \" + stype);","typeGuard":null,"tryCatchPattern":"try { session.execute(ddl); }\ncatch (InvalidRequestException e) { if (e.getMessage().contains(\"return type must be the same\")) alignStypeWithSfunc(ddl); else throw e; }","preventionTips":["Declare SFUNC return type and STYPE together in one place in your schema tooling","Re-derive STYPE from the function metadata instead of hardcoding it","Review aggregates whenever the underlying state function's signature changes"],"tags":["cql","aggregate","type-mismatch","sfunc"],"backgroundTag":"type-mismatch","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"}