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

  1. Add an explicit cast: SELECT (int)? FROM t
  2. Use a literal of the intended type instead of a bare bind marker
  3. 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

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


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);
        }

        @Override

View on GitHub (pinned to 88fd0f6a0e)