apache/cassandra · error · InvalidRequestException
Cannot infer type for term
Error message
Cannot infer type for term
What it means
A bare term/bind marker in the SELECT clause (e.g. SELECT ?) must have a known CQL type to create a receiver. If the selectable's exact type cannot be resolved from the table and no expectedType was passed down, type inference fails and the query is rejected with a hint to use a cast.
Solutions
- Add an explicit cast: SELECT (int)? FROM t
- Use a literal of the intended type instead of a bare bind marker
- Wrap the term in a typed function such as blobAsInt(...) or toTimestamp(...) to fix the type
Example fix
// before SELECT ? FROM t; // after SELECT (int)? FROM t;
Defensive patterns
Strategy: validation
Validate before calling
// ensure the term type is inferable before preparing
if (termType == null) addCast("SELECT (int)? ..."); Prevention
- Never leave bare bind markers in the SELECT clause
- Cast inferred-type terms explicitly
- Use literals of the exact intended type
When it happens
Trigger: SELECT ? FROM t where the term is a bind marker (or literal needing inference) with no surrounding function/cast that fixes its type.
Common situations: Users write SELECT ? or pass constants wrapped in functions whose overload is ambiguous; Cassandra cannot determine which type the marker should bind to.
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
- Cannot infer type for term
- Invalid map literal for
- Invalid null value for slice selection on
- Invalid unset value for element selection on
- Unexpected receiver type
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/e27ec426c9443b84.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/selection/Selectable.java:217
* But in the 2nd case, we're fine and can use the expectedType to "prepare" the bind marker/collect the bound type.
*
* Further, the term might not be a bind marker, in which case we sometimes can default to some most-general type. For instance, in
* SELECT 3 FROM foo
* we'll just default the type to 'varint' as that's the most generic type for the literal '3' (this is mostly for convenience, the query
* is not terribly useful in practice and use can force the type as for the bind marker case through "SELECT (int)3 FROM foo").
* But note that not all literals can have such default type. For instance, there is no way to infer the type of a UDT literal in a vacuum,
* and so we simply error out if we have something like:
* SELECT { foo: 'bar' } FROM foo
*
* Lastly, note that if the term is a terminal literal, we don't have to check it's compatibility with 'expectedType' as any incompatibility
* would have been found at preparation time.
*/
AbstractType<?> type = getExactTypeIfKnown(table.keyspace);
if (type == null)
{
type = expectedType;
if (type == null)
throw new InvalidRequestException("Cannot infer type for term " + this + " in selection clause (try using a cast to force a type)");
}
// The fact we default the name to "[selection]" inconditionally means that any bind marker in a
// selection will have this name. Which isn't terribly helpful, but it's unclear how to provide
// something a lot more helpful and in practice user can bind those markers by position or, even better,
// use bind markers.
Term term = rawTerm.prepare(table.keyspace, new ColumnSpecification(table.keyspace, table.name, bindMarkerNameInSelection, type));
term.collectMarkerSpecification(boundNames, table);
return TermSelector.newFactory(rawTerm.getText(), term, type);
}
@Override
public AbstractType<?> getExactTypeIfKnown(String keyspace)
{
return rawTerm.getExactTypeIfKnown(keyspace);
}
@OverrideView on GitHub (pinned to 88fd0f6a0e)