{"record":{"id":"9ba2c04b44040105","repo":"apache/cassandra","slug":"conditional-batch-statements-cannot-include-mutati","errorCode":null,"errorMessage":"Conditional BATCH statements cannot include mutations for virtual tables","messagePattern":"Conditional BATCH statements cannot include mutations for virtual tables","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/BatchStatement.java","lineNumber":309,"sourceCode":"            throw new InvalidRequestException(\"Cannot provide custom timestamp for a BATCH containing counters\");\n\n        if (isCounter() && hasNonCounters)\n            throw new InvalidRequestException(\"Cannot include non-counter statement in a counter batch\");\n\n        if (hasCounters && hasNonCounters)\n            throw new InvalidRequestException(\"Counter and non-counter mutations cannot exist in the same batch\");\n\n        if (isLogged() && hasCounters)\n            throw new InvalidRequestException(\"Cannot include a counter statement in a logged batch\");\n\n        if (isLogged() && hasVirtualTables)\n            throw new InvalidRequestException(\"Cannot include a virtual table statement in a logged batch\");\n\n        if (hasVirtualTables && hasRegularTables)\n            throw new InvalidRequestException(\"Mutations for virtual and regular tables cannot exist in the same batch\");\n\n        if (hasConditions && hasVirtualTables)\n            throw new InvalidRequestException(\"Conditional BATCH statements cannot include mutations for virtual tables\");\n\n        if (hasConditions)\n        {\n            String ksName = null;\n            String cfName = null;\n            for (ModificationStatement stmt : statements)\n            {\n                if (ksName != null && (!stmt.keyspace().equals(ksName) || !stmt.table().equals(cfName)))\n                    throw new InvalidRequestException(\"Batch with conditions cannot span multiple tables: \" + stmt.source);\n                ksName = stmt.keyspace();\n                cfName = stmt.table();\n            }\n        }\n    }\n\n    private boolean isCounter()\n    {\n        return type == Type.COUNTER;","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java#L291-L327","documentation":"InvalidRequestException from BatchStatement.validate: the batch carries conditions (IF ... — a conditional/LWT batch) and includes mutations against virtual tables. Virtual tables cannot participate in CAS/conditional logic, so their presence alongside conditions is rejected during batch validation (companion guards reject counters in logged batches and mixed counter/non-counter batches).","triggerScenarios":"'BEGIN BATCH ... UPDATE system_views.v ... IF EXISTS; APPLY BATCH' — applying LWT conditions to virtual table mutations.","commonSituations":"Developers assuming virtual tables support compare-and-set like regular tables; generated conditional batches including virtual tables.","solutions":["Remove virtual table statements from conditional batches — LWT applies only to regular tables","Move the conditional logic to regular table mutations only","If conditional behavior on virtual data is needed, implement it application-side"],"exampleFix":"// before\nBEGIN BATCH UPDATE ks.t SET v = 2 WHERE k = 1 IF v = 1;\n             UPDATE system_views.x SET a = 1 WHERE b = 2; APPLY BATCH;\n// after\nBEGIN BATCH UPDATE ks.t SET v = 2 WHERE k = 1 IF v = 1; APPLY BATCH;\n","handlingStrategy":"validation","validationCode":"if (batchHasConditions && stmts.stream().anyMatch(s -> s.getTable().isVirtual()))\n    throw new IllegalArgumentException(\"LWT batches cannot include virtual tables\");","typeGuard":null,"tryCatchPattern":"catch (InvalidRequestException e) { if (e.getMessage().contains(\"Conditional BATCH\") && e.getMessage().contains(\"virtual\")) { dropVirtualStatementsAndRetry(); } else throw e; }","preventionTips":["Only attach IF conditions to statements on regular tables","Audit generated LWT batches for virtual-table targets"],"tags":["cql","batch","lwt","virtual-tables"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}