{"record":{"id":"18c6475132710c65","repo":"hibernate/hibernate-orm","slug":"function-argument-s-of-type-s-at-specified-p","errorCode":null,"errorMessage":"Function argument [%s] of type [%s] at specified position [%d] in call arguments was not typed as an allowable function return type","messagePattern":"Function argument \\[(.+?)\\] of type \\[(.+?)\\] at specified position \\[(.+?)\\] in call arguments was not typed as an allowable function return type","errorType":"exception","errorClass":"FunctionArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardFunctionReturnTypeResolvers.java","lineNumber":205,"sourceCode":"\t\t\t//type specified in the function template (i.e. in the Dialect) and a type\n\t\t\t//that is determined by how the function is used in the HQL query. In essence\n\t\t\t//the types are compatible if the map to the same JDBC type, of if they are\n\t\t\t//both numeric types.\n\t\t\treturn isAssignableTo( defined.getJdbcMapping(), implied.getJdbcMapping() );\n\t\t}\n\t}\n\n\tpublic static ReturnableType<?> extractArgumentType(List<? extends SqmTypedNode<?>> arguments, int position) {\n\t\tfinal SqmTypedNode<?> specifiedArgument = arguments.get( position - 1 );\n\t\tfinal SqmExpressible<?> specifiedArgType = getArgumentExpressible( specifiedArgument );\n\t\tif ( specifiedArgType == null ) {\n\t\t\treturn null;\n\t\t}\n\t\telse if ( specifiedArgType instanceof ReturnableType<?> returnableType ) {\n\t\t\treturn returnableType;\n\t\t}\n\t\telse {\n\t\t\tthrow new FunctionArgumentException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Function argument [%s] of type [%s] at specified position [%d] in call arguments was not typed as an allowable function return type\",\n\t\t\t\t\t\t\tspecifiedArgument,\n\t\t\t\t\t\t\tspecifiedArgType,\n\t\t\t\t\t\t\tposition\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate static SqmExpressible<?> getArgumentExpressible(SqmTypedNode<?> specifiedArgument) {\n\t\tfinal SqmExpressible<?> expressible = specifiedArgument.getExpressible();\n\t\treturn expressible != null ? expressible.getSqmType() : null;\n\t}\n\n//\tpublic static JdbcMapping extractArgumentJdbcMapping(\n//\t\t\tTypeConfiguration typeConfiguration,","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/StandardFunctionReturnTypeResolvers.java#L187-L223","documentation":"extractArgumentType(arguments, position) is the helper behind useArgType(...) return-type resolvers: it takes the type of the argument at the given 1-based position and reuses it as the function's return type. If that argument's SqmExpressible is non-null but not a ReturnableType (i.e. it cannot be produced as a function result), it throws FunctionArgumentException while the query is interpreted. This is a function-authoring mismatch: the chosen argument position cannot drive the return type.","triggerScenarios":"A custom function (often set-returning, built with SetReturningFunctionTypeResolverBuilder.useArgType(component, pos)) whose referenced argument resolves to a non-returnable expressible - e.g. an entity-typed or embedded-typed path - so extractArgumentType hits the else branch.","commonSituations":"Reusing a working function template against a new entity whose attribute at that position is an embeddable or association; changing an attribute from basic to embedded and forgetting the function definition; building generate_series/unnest-style functions where the argument position drifted after an edit.","solutions":["Point useArgType at an argument position that is basic-typed (String, Integer, ...).","Force the input shape with an HQL cast(): my_func(cast(e.embeddedField as string)).","If the return type does not really depend on an argument, use invariant(...) with a fixed type instead.","Dereference to a basic attribute before passing: my_func(e.embedded.someField)."],"exampleFix":"// before - arg 1 is an embeddable path, not a ReturnableType\nresolverBuilder.useArgType(\"value\", 1)\n\n// after - fixed return type; argument shape no longer matters\nresolverBuilder.invariant(\"value\", StandardBasicTypes.STRING)","handlingStrategy":"try-catch","validationCode":"static boolean argumentIsReturnable(List<? extends SqmTypedNode<?>> arguments, int position) {\n    if (arguments.size() < position) return false;\n    return arguments.get(position - 1).getNodeType() instanceof ReturnableType;\n}","typeGuard":null,"tryCatchPattern":"try {\n    return em.createQuery(hql).getResultList();\n} catch (org.hibernate.query.sqm.produce.function.FunctionArgumentException e) {\n    log.error(\"Function argument not usable as return type: {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Document, per custom function, which argument positions must stay basic-typed for useArgType.","Run each custom function against the real mapped entities in CI so embedded/association drift is caught early.","Prefer invariant return types unless the type truly tracks an argument."],"tags":["hibernate","sqm","function","return-type","custom-function"],"backgroundTag":"function-return-type-resolution-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}