apache/cassandra · error · IllegalArgumentException
Invalid number of values. Expecting
Error message
Invalid number of values. Expecting %d but got %d
What it means
TupleType.newValue(Object...) builds a CQL tuple value and requires exactly one argument per component type defined in the tuple. This IllegalArgumentException is thrown when the number of supplied values differs from types.size(). CQL tuples are fixed-arity, so the arity mismatch is rejected before any per-component type check happens.
Solutions
- Check tupleType.getComponentTypes().size() and supply exactly that many arguments
- Re-read cluster metadata if the schema changed and your cached TupleType is stale
- Spread collection values: newValue(list.toArray()) for a tuple matching the list size
- Use TupleType.newValue() (empty) plus per-index setters if values are optional
Example fix
// before TupleValue v = tupleType.newValue(values); // values is a List -> counted as 1 arg // after TupleValue v = tupleType.newValue(values.toArray());
Defensive patterns
Strategy: validation
Validate before calling
static TupleValue safeNewValue(TupleType tt, Object... values) {
int expected = tt.getComponentTypes().size();
if (values.length != expected)
throw new IllegalArgumentException("need " + expected + " values, got " + values.length);
return tt.newValue(values);
} Type guard
static boolean matchesArity(TupleType tt, Object[] values) {
return values.length == tt.getComponentTypes().size();
} Try / catch
try {
TupleValue v = tupleType.newValue(values);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Invalid number of values")) {
// re-fetch schema metadata or fix arity
}
} Prevention
- Spread collections with toArray() instead of passing the collection itself
- Refresh TupleType metadata after schema ALTERs
- Assert arity equals getComponentTypes().size() before constructing values
When it happens
Trigger: Calling tupleType.newValue(v1, v2) on a 3-component tuple type, or passing a single array/list of values as one varargs element (e.g. newValue(list) instead of newValue(list.toArray())).
Common situations: Schema drift after an ALTER TYPE adding a tuple component, generating values from a metadata-driven loop whose size differs from the tuple definition, or forgetting to spread a collection into varargs.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid operation ( ) for tuple column
- Not enough bytes to read %dth component
- Not enough bytes to read %dth
- Not enough bytes to read size of %dth component
- Secondary indexes are not supported on tuples containing…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/2b320c49f9af39f2.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/TupleType.java:106
/**
* Returns a new value for this tuple type that uses the provided values for the components.
*
* <p>The numbers of values passed to this method must correspond to the number of components in
* this tuple type. The {@code i}th parameter value will then be assigned to the {@code i}th
* component of the resulting tuple value.
*
* @param values the values to use for the component of the resulting tuple.
* @return a new tuple values based on the provided values.
* @throws IllegalArgumentException if the number of {@code values} provided does not correspond
* to the number of components in this tuple type.
* @throws InvalidTypeException if any of the provided value is not of the correct type for the
* component.
*/
public TupleValue newValue(Object... values)
{
if (values.length != types.size())
throw new IllegalArgumentException(
String.format(
"Invalid number of values. Expecting %d but got %d", types.size(), values.length));
TupleValue t = newValue();
for (int i = 0; i < values.length; i++)
{
DataType dataType = types.get(i);
if (values[i] == null) t.setValue(i, null);
else
t.setValue(
i, codecRegistry.codecFor(dataType, values[i]).serialize(values[i], protocolVersion));
}
return t;
}
@Override
public boolean isFrozen()
{View on GitHub (pinned to 88fd0f6a0e)