{"record":{"id":"63ceb09a272b9f2a","repo":"apache/cassandra","slug":"cannot-provide-custom-timestamp-for-conditional-ba","errorCode":null,"errorMessage":"Cannot provide custom timestamp for conditional BATCH","messagePattern":"Cannot provide custom timestamp for conditional BATCH","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/BatchStatement.java","lineNumber":262,"sourceCode":"    @Override\n    public void authorize(ClientState state) throws InvalidRequestException, UnauthorizedException\n    {\n        ModificationStatement.TableAuthorizationState authorizationState = new ModificationStatement.TableAuthorizationState();\n        for (ModificationStatement statement : statements)\n            statement.authorize(state, authorizationState);\n    }\n\n    // Validates a prepared batch statement without validating its nested statements.\n    public void validate() throws InvalidRequestException\n    {\n        if (attrs.isTimeToLiveSet())\n            throw new InvalidRequestException(\"Global TTL on the BATCH statement is not supported.\");\n\n        boolean timestampSet = attrs.isTimestampSet();\n        if (timestampSet)\n        {\n            if (hasConditions)\n                throw new InvalidRequestException(\"Cannot provide custom timestamp for conditional BATCH\");\n\n            if (isCounter())\n                throw new InvalidRequestException(\"Cannot provide custom timestamp for counter BATCH\");\n        }\n\n        boolean hasCounters = false;\n        boolean hasNonCounters = false;\n\n        boolean hasVirtualTables = false;\n        boolean hasRegularTables = false;\n\n        for (ModificationStatement statement : statements)\n        {\n            if (timestampSet && statement.isTimestampSet())\n                throw new InvalidRequestException(\"Timestamp must be set either on BATCH or individual statements: \" + statement.source);\n\n            if (statement.isCounter())\n                hasCounters = true;","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java#L244-L280","documentation":"A batch that contains conditional statements (LWT, e.g. IF NOT EXISTS / IF condition) cannot also carry a batch-level custom timestamp USING TIMESTAMP, because condition evaluation determines the write timestamp. BatchStatement.validate() throws this InvalidRequestException.","triggerScenarios":"BEGIN BATCH ... USING TIMESTAMP 12345 ... containing any statement with conditions (hasConditions), executed directly or via prepare.","commonSituations":"Combining compare-and-set workflows with explicit timestamps; query builders that always append USING TIMESTAMP.","solutions":["Remove USING TIMESTAMP from the conditional batch","Move the conditional statements to a separate batch without a custom timestamp","Use per-statement timestamps only on non-conditional statements in a different batch"],"exampleFix":"// before\nBEGIN BATCH USING TIMESTAMP 1234 INSERT INTO t ... IF NOT EXISTS; APPLY BATCH;\n// after\nBEGIN BATCH INSERT INTO t ... IF NOT EXISTS; APPLY BATCH; // no USING TIMESTAMP","handlingStrategy":"validation","validationCode":"boolean hasConditions = statements.stream().anyMatch(s -> s.hasConditions());\nif (hasConditions && batchUsesTimestamp) throw new IllegalArgumentException(\"drop USING TIMESTAMP for conditional batches\");","typeGuard":null,"tryCatchPattern":"try { session.execute(batch); }\ncatch (InvalidQueryException e) {\n    if (e.getMessage().contains(\"custom timestamp for conditional BATCH\")) { /* remove USING TIMESTAMP */ }\n}","preventionTips":["Never combine USING TIMESTAMP with IF EXISTS / IF NOT EXISTS / IF conditions in batches","Keep LWT batches separate from timestamp-controlled write batches"],"tags":["cql","batch","lwt"],"backgroundTag":"conflicting-config-options","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"}