{"record":{"id":"278d9d3958c82b59","repo":"apache/cassandra","slug":"final-function-s-doesn-t-exist","errorCode":null,"errorMessage":"Final function %s doesn't exist","messagePattern":"Final function (.+?) doesn't exist","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java","lineNumber":160,"sourceCode":"\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());\n\n            // override return type with that of the final function\n            returnType = finalFunction.returnType();\n        }\n\n        /*\n         * Validate initial condition\n         */\n\n        ByteBuffer initialValue = null;\n        if (null != rawInitialValue)\n        {\n            String term = rawInitialValue.toString();\n            initialValue = Term.asBytes(keyspaceName, term, stateType);\n","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateAggregateStatement.java#L142-L178","documentation":"Thrown by CreateAggregateStatement.apply when a CREATE AGGREGATE statement names a FINALFUNC that does not exist in the target keyspace with a signature of exactly one argument of the aggregate's state type. Cassandra resolves the final function during schema application and refuses to create the aggregate if it cannot be found.","triggerScenarios":"CREATE AGGREGATE ... FINALFUNC <name> where no user-defined scalar function of that name accepting a single argument of the state type exists in the keyspace (or the function exists but with a different argument type).","commonSituations":"Typo in the final function name; final function created in a different keyspace than the aggregate; final function declared with a parameter type that differs from the state type; FINALFUNC created after the aggregate was attempted.","solutions":["Create the missing scalar function first: CREATE FUNCTION <ks>.<finalfunc>(state <stateType>) RETURNS NULL ON NULL INPUT ...","Verify the final function's argument type exactly matches the aggregate's STYPE.","Check you are in the same keyspace (or fully qualify the function name with the keyspace).","If the aggregate needs no final transformation, drop the FINALFUNC clause entirely."],"exampleFix":"// before\nCREATE AGGREGATE ks.avg(int) SFUNC avg_state STYPE avg_state FINALFUNC divide_by_count;\n// (divide_by_count(int) does not exist)\n// after\nCREATE FUNCTION ks.divide_by_count(total avg_state) RETURNS NULL ON NULL INPUT RETURNS int ...;\nCREATE AGGREGATE ks.avg(int) SFUNC avg_state STYPE avg_state FINALFUNC divide_by_count;","handlingStrategy":"validation","validationCode":"// pseudocode before CREATE AGGREGATE\nvar finalFunc = keyspace.userFunctions.find(finalFuncName, List.of(stateType));\nif (finalFunc.isEmpty()) throw new IllegalStateException(\n    \"FINALFUNC \" + finalFuncName + \"(\" + stateType + \") not found in keyspace \" + keyspace);","typeGuard":null,"tryCatchPattern":"// catch InvalidRequestException from session.execute\ntry { session.execute(ddl); }\ncatch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"doesn't exist\")) { /* create the final function, then retry */ }\n    else throw e;\n}","preventionTips":["Create all scalar functions before aggregates in DDL scripts.","Qualify function names with the keyspace explicitly.","Keep STYPE and FINALFUNC argument type in sync in one place (a shared template)."],"tags":["cql","user-defined-function","schema"],"backgroundTag":"resource-not-found","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"}