apache/cassandra · error · SyntaxException
(dynamic first syntax error message from parser/lexer)
Error message
(dynamic first syntax error message from parser/lexer)
What it means
ErrorCollector.throwFirstSyntaxError rethrows the first syntax error accumulated by the ANTLR ErrorCollector as a SyntaxException. The message text is dynamic — produced by the parser/lexer (e.g. 'no viable alternative at input ...', 'missing ... at ...', 'extraneous input ...'). It is the detailed counterpart of the generic parseAny failure and is thrown by parseAnyUnhandled.
Source
Thrown at src/java/org/apache/cassandra/cql3/ErrorCollector.java:102
/**
* {@inheritDoc}
*/
@Override
public void syntaxError(BaseRecognizer recognizer, String errorMsg)
{
errorMsgs.add(errorMsg);
}
/**
* Throws the first syntax error found by the lexer or the parser if it exists.
*
* @throws SyntaxException the syntax error.
*/
public void throwFirstSyntaxError() throws SyntaxException
{
if (!errorMsgs.isEmpty())
throw new SyntaxException(errorMsgs.getFirst());
}
/**
* Appends a query snippet to the message to help the user to understand the problem.
*
* @param parser the parser used to parse the query
* @param builder the <code>StringBuilder</code> used to build the error message
*/
private void appendQuerySnippet(Parser parser, StringBuilder builder)
{
TokenStream tokenStream = parser.getTokenStream();
int index = tokenStream.index();
int size = tokenStream.size();
Token from = tokenStream.get(getSnippetFirstTokenIndex(index));
Token to = tokenStream.get(getSnippetLastTokenIndex(index, size));
Token offending = tokenStream.get(getOffendingTokenIndex(index, size));
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Read the specific message: it names the offending input position — fix that token
- Quote reserved keywords as identifiers with double quotes
- Check the CQL grammar for your Cassandra version for unsupported syntax
- Run the query in cqlsh to interactively iterate on the syntax
Example fix
// before String cql = "SELECT count FROM tbl"; // 'count' needs aggregation syntax // after String cql = "SELECT count(*) FROM tbl";
Defensive patterns
Strategy: validation
Validate before calling
private static void requireCql(String cql) {
if (cql == null || cql.trim().isEmpty()) throw new IllegalArgumentException("Empty CQL");
if (cql.chars().filter(c -> c == '\'').count() % 2 != 0) throw new IllegalArgumentException("Unbalanced quotes");
if (cql.chars().filter(c -> c == '(').count() != cql.chars().filter(c -> c == ')').count()) throw new IllegalArgumentException("Unbalanced parens");
} Try / catch
try { parse(cql); } catch (SyntaxException e) { throw new IllegalArgumentException("CQL syntax error: " + e.getMessage(), e); } Prevention
- Quote reserved keywords with double quotes when used as identifiers
- Validate syntax against the grammar of the target Cassandra version
- Iterate queries in cqlsh before embedding them
- Avoid hand-concatenating CQL from untrusted fragments
When it happens
Trigger: Any CQL statement or fragment parsed via parseAnyUnhandled where ANTLR reports syntax errors: bad tokens, misplaced keywords, unterminated strings, invalid type names.
Common situations: Typos in CQL keywords; using reserved words as bare identifiers; copy-pasted SQL from other databases; version-specific grammar features used against an older Cassandra.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid or malformed
- Multiple definition for property '%s'
- Failed parsing %s: [%s] reason: %s %s
- Could not decode JSON string as a map: %s. (String was: %s)
- Failed parsing statement: [%s] reason: %s %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ac0704939813cf79.
Report an issue: GitHub.