{"record":{"id":"08e099c8f68a2318","repo":"apache/cassandra","slug":"can-not-add-a-new-in-progress-sequence-for-s-sin","errorCode":null,"errorMessage":"Can not add a new in-progress sequence for %s, since there's already one associated with it: %s","messagePattern":"Can not add a new in-progress sequence for (.+?), since there's already one associated with it: (.+?)","errorType":"exception","errorClass":"Transformation.RejectedTransformationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/sequences/InProgressSequences.java","lineNumber":130,"sourceCode":"    {\n        return state.containsKey(key);\n    }\n\n    public MultiStepOperation<?> get(MultiStepOperation.SequenceKey key)\n    {\n        return state.get(key);\n    }\n\n    public boolean isEmpty()\n    {\n        return state.isEmpty();\n    }\n\n    public InProgressSequences with(MultiStepOperation.SequenceKey key, MultiStepOperation<?> sequence)\n    {\n        if (contains(key))\n        {\n            throw new Transformation.RejectedTransformationException(String.format(\"Can not add a new in-progress sequence for %s, \" +\n                                                                                   \"since there's already one associated with it: %s\",\n                                                                                   key,\n                                                                                   get(key)));\n        }\n\n        ImmutableMap.Builder<MultiStepOperation.SequenceKey, MultiStepOperation<?>> builder = ImmutableMap.builder();\n        builder.put(key, sequence);\n        for (Map.Entry<MultiStepOperation.SequenceKey, MultiStepOperation<?>> e : state.entrySet())\n        {\n            if (e.getKey().equals(key))\n                continue;\n            builder.put(e.getKey(), e.getValue());\n        }\n        return new InProgressSequences(lastModified, builder.build());\n    }\n\n    public <T2, T1 extends MultiStepOperation<T2>> InProgressSequences with(MultiStepOperation.SequenceKey key, Function<T1, T1> update)\n    {","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/sequences/InProgressSequences.java#L112-L148","documentation":"InProgressSequences.with() rejects adding a new MultiStepOperation under a SequenceKey that already has one, throwing RejectedTransformationException. TCM enforces at most one in-progress sequence per key so transformations remain unambiguous. This is a commit-time conflict, surfaced as a rejected metadata transformation.","triggerScenarios":"addSequence() attempting to register a bootstrap/replace/move sequence whose SequenceKey already maps to another sequence in the ClusterMetadata transformation, typically a duplicate bootstrap for the same node or a retried sequence registration without cancelling the old one.","commonSituations":"Two operators concurrently starting sequences for the same node; retry logic re-submitting a sequence registration after a timeout while the first succeeded; automation double-firing a bootstrap request.","solutions":["Cancel or let the existing sequence finish before starting a new one for the same key","Check inProgressSequences for the key to see the conflicting sequence and its state","Make client/automation code idempotent: reuse the existing sequence instead of re-registering","Handle RejectedTransformationException as an expected conflict and retry after the current sequence completes"],"exampleFix":"// before\nmetadata.transformer().with(key, newSequence).commit();\n// after\nif (!ClusterMetadata.current().inProgressSequences.contains(key))\n    metadata.transformer().with(key, newSequence).commit();\nelse\n    logger.warn(\"Sequence already in progress for {}: {}\", key, ClusterMetadata.current().inProgressSequences.get(key));","handlingStrategy":"try-catch","validationCode":"if (ClusterMetadata.current().inProgressSequences.contains(key))\n    throw new IllegalStateException(\"Sequence already registered for \" + key);","typeGuard":null,"tryCatchPattern":"try { transformer.with(key, seq).commit(); } catch (Transformation.RejectedTransformationException e) { logger.warn(\"Conflicting sequence for {}: {}\", key, e.getMessage()); waitForExistingSequenceCompletion(key); retry(); }","preventionTips":["Serialize sequence-start commands through a single coordination point","Make registration idempotent: reuse an existing sequence for the same key","Always cancel a failed sequence before re-registering"],"tags":["transformation-rejected","conflict","sequence","cluster-metadata"],"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-17T15:17:12.973Z"}