apache/cassandra · error · IllegalArgumentException

could not parse update query

Error message

could not parse update query:${queryString}

What it means

CASQuery must parse the prepared statement's query string as an UPDATE statement (via the CQL ANTLR parser) to extract the IF conditions. If the query string cannot be parsed as an update statement, the RecognitionException is wrapped in an IllegalArgumentException including the offending query text.

Solutions

  1. Ensure the CAS statement is a valid UPDATE ... IF EXISTS / IF col=val query
  2. Validate the CQL statement in cqlsh before adding it to the stress profile
  3. Check the query string for syntax errors (missing commas, wrong keywords)

Example fix

// before
stmt: INSERT INTO t (k, v) VALUES (?, ?) IF NOT EXISTS
// after
stmt: UPDATE t SET v = ? WHERE k = ? IF v = ?
Defensive patterns

Strategy: try-catch

Try / catch

try { CQLFragmentParser.parseAnyUnhandled(CqlParser::updateStatement, stmt.getQueryString()); }
catch (RecognitionException e) { throw new IllegalArgumentException("CAS statement must be a valid UPDATE: " + stmt.getQueryString(), e); }

Prevention

When it happens

Trigger: Using a CAS operation in a stress profile whose prepared statement is not a syntactically valid UPDATE statement (e.g. an INSERT with conditions, a malformed UPDATE, or a SELECT passed where CAS expects UPDATE).

Common situations: Typos in the profile's CAS statement; pointing CAS at an INSERT or conditional INSERT statement instead of UPDATE ... IF; version drift between profile CQL syntax and the parser grammar.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/5659ce7f37c62d29. Report an issue: GitHub.

Appendix: source

Thrown at tools/stress/src/org/apache/cassandra/stress/operations/userdefined/CASQuery.java:81

    private PreparedStatement casReadConditionStatement;

    public CASQuery(Timer timer, StressSettings settings, PartitionGenerator generator, SeedManager seedManager, PreparedStatement statement, ConsistencyLevel cl, ArgSelect argSelect, final String tableName)
    {
        super(timer, settings, new DataSpec(generator, seedManager, new DistributionFixed(1), settings.insert.rowPopulationRatio.get(), argSelect == SchemaStatement.ArgSelect.MULTIROW ? statement.getVariables().size() : 1), statement,
              statement.getVariables().asList().stream().map(ColumnDefinitions.Definition::getName).collect(Collectors.toList()), cl);

        if (argSelect != SchemaStatement.ArgSelect.SAMEROW)
            throw new IllegalArgumentException("CAS is supported only for type 'samerow'");

        ModificationStatement.Parsed modificationStatement;
        try
        {
            modificationStatement = CQLFragmentParser.parseAnyUnhandled(CqlParser::updateStatement,
                    statement.getQueryString());
        }
        catch (RecognitionException e)
        {
            throw new IllegalArgumentException("could not parse update query:" + statement.getQueryString(), e);
        }

        final List<ColumnCondition.Raw> casConditionList = modificationStatement.getConditions();
        List<Integer> casConditionIndex = new ArrayList<>();

        boolean first = true;
        StringBuilder casReadConditionQuery = new StringBuilder();
        casReadConditionQuery.append("SELECT ");
        for (final ColumnCondition.Raw condition : casConditionList)
        {
            if (!condition.containsBindMarkers())
            {
                //condition uses static value, ignore it
                continue;
            }
            if (!first)
            {
                casReadConditionQuery.append(", ");

View on GitHub (pinned to 88fd0f6a0e)