apache/cassandra · error · IllegalStateException
Function argument is not a UDT but a
Error message
Function argument is not a UDT but a ${dataType.getName()} What it means
UDFContextImpl.newUDTValue expects the DataType of a function argument (or named/indexed argument) to be a UserType. When it is any other type, an IllegalStateException naming the actual type is thrown.
Solutions
- Only call newUDTValue/newArgUDTValue for arguments declared as a UDT in CREATE FUNCTION
- Check the argument's declared type and use the matching accessor (newTupleValue for tuples, newSet/List/MapValue for collections)
- If the schema changed, update the UDF code to match the new argument types
Example fix
// before UDTValue v = context.newArgUDTValue(0); // arg 0 is an int // after int x = context.getInt(0); // use type-correct accessor
Defensive patterns
Strategy: type-guard
Validate before calling
// Only request UDT values for UDT-typed arguments:
if (!(argType instanceof UserType)) throw new IllegalArgumentException("arg is not a UDT: " + argType); Type guard
boolean isUdt(DataType t) { return t instanceof UserType; } Try / catch
try { UDTValue v = ctx.newArgUDTValue(i); }
catch (IllegalStateException e) {
if (e.getMessage().contains("not a UDT")) { /* fall back to a type-correct accessor */ }
else throw e;
} Prevention
- Map each UDF argument's CQL type to the correct UDFContext accessor before coding the body
- Re-check argument types after any schema change to UDT columns
When it happens
Trigger: Calling udfContext.newUDTValue() (or newArgUDTValue for an argument) whose declared CQL type is not a user-defined type — e.g. an int, text, or tuple argument.
Common situations: Copy-pasted UDF context code assuming all arguments are UDTs; schema changed so a column that was a UDT is now another type; wrong argument index/name passed to newArgUDTValue.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Function argument is not a tuple type but a
- Cannot replace function
- Expected a map, but got a
- Function does not declare an argument with index
- Invalid operation ( ) for non-UDT column
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d27bac654dbac32d.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/functions/UDFContextImpl.java:120
return newTupleValue(getArgumentTypeByIndex(argNum).toDataType());
}
public TupleValue newReturnTupleValue()
{
return newTupleValue(returnType.toDataType());
}
public TupleValue newTupleValue(String cqlDefinition)
{
AbstractType<?> abstractType = CQLTypeParser.parse(keyspace, cqlDefinition, metadata.get().types);
DataType dataType = JavaDriverUtils.driverType(abstractType);
return newTupleValue(dataType);
}
private static UDTValue newUDTValue(DataType dataType)
{
if (!(dataType instanceof UserType))
throw new IllegalStateException("Function argument is not a UDT but a " + dataType.getName());
UserType userType = (UserType) dataType;
return userType.newValue();
}
private static TupleValue newTupleValue(DataType dataType)
{
if (!(dataType instanceof TupleType))
throw new IllegalStateException("Function argument is not a tuple type but a " + dataType.getName());
TupleType tupleType = (TupleType) dataType;
return tupleType.newValue();
}
private UDFDataType getArgumentTypeByIndex(int index)
{
if (index < 0 || index >= argTypes.size())
throw new IllegalArgumentException("Function does not declare an argument with index " + index);
return argTypes.get(index);
}View on GitHub (pinned to 88fd0f6a0e)