{"record":{"id":"0f9fbeb272a618c5","repo":"apache/cassandra","slug":"token-required-when-no-move-sequence-is-in-progres","errorCode":null,"errorMessage":"Token required when no MOVE sequence is in progress.","messagePattern":"Token required when no MOVE sequence is in progress\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tools/CMSOfflineTool.java","lineNumber":491,"sourceCode":"        private String outputFilePath;\n\n        @Override\n        protected void execute(Output output) throws IOException\n        {\n            // Took the reference from org.apache.cassandra.tcm.sequences.SingleNodeSequences.move\n            ClusterMetadata metadata = parseClusterMetadata();\n            NodeId nodeId = nodeIdentifierOption.getNodeId(metadata);\n\n            if (metadata.inProgressSequences.contains(nodeId))\n            {\n                ClusterMetadata updatedMetadata = finishInProgressSequence(nodeId, token, metadata);\n                writeMetadata(output, updatedMetadata, outputFilePath);\n                return;\n            }\n\n            if (null == token)\n            {\n                throw new IllegalArgumentException(\"Token required when no MOVE sequence is in progress.\");\n            }\n            metadata.partitioner.getTokenFactory().validate(token);\n            Token toToken = metadata.partitioner.getTokenFactory().fromString(token);\n            if (metadata.tokenMap.tokens().contains(toToken))\n            {\n                NodeId tokenOwnerId = metadata.tokenMap.owner(toToken);\n                throw new IllegalArgumentException(\"Target token \" + toToken + \" is already owned by node \" + tokenOwnerId.id());\n            }\n            if (metadata.tokenMap.tokens(nodeId).size() > 1)\n            {\n                throw new UnsupportedOperationException(\"This node has more than one token and cannot be moved thusly.\");\n            }\n\n            PrepareMove prepareMove = new PrepareMove(nodeId, Set.of(toToken), new UniformRangePlacement(), false);\n            ClusterMetadata updatedMetadata = prepareMove.execute(metadata).success().metadata;\n            updatedMetadata = updatedMetadata.inProgressSequences.get(nodeId).applyTo(updatedMetadata).success().metadata;\n            writeMetadata(output, updatedMetadata, outputFilePath);\n        }","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tools/CMSOfflineTool.java#L473-L509","documentation":"The move operation can either finish an in-progress MOVE sequence (using its tokens) or start a new move, which requires an explicit target token. When no MOVE is in progress and no --token was supplied, this IllegalArgumentException is thrown because there is nothing to move to.","triggerScenarios":"Running the move subcommand in `execute` when metadata.inProgressSequences.get(nodeId) is not a MOVE (or absent) and the `token` argument is null.","commonSituations":"Operator forgets the --token flag when moving a node; operator assumed a MOVE was still in progress (from a previous interrupted run) but the metadata shows it completed or was cancelled.","solutions":["Re-run the command with a target token, e.g. `cms move -ip <ip> --token <token>`.","If a MOVE was expected to be in progress, check metadata.inProgressSequences for the node and resume with the correct subcommand.","Validate the token is within the partitioner range before retrying."],"exampleFix":"// before\nbin/cms move -ip 10.0.0.5\n// after\nbin/cms move -ip 10.0.0.5 --token 3074457345618258602","handlingStrategy":"validation","validationCode":"if (!hasMoveInProgress(meta, nodeId) && token == null)\n    throw new IllegalArgumentException(\"--token is required when no MOVE sequence is in progress for \" + nodeId);","typeGuard":null,"tryCatchPattern":"try { tool.move(nodeId, null); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"Token required\")) { retryWithToken(); } else throw e; }","preventionTips":["Always pass --token when starting a new move; omit it only to resume an in-progress one.","Confirm whether a MOVE is actually in progress before omitting the token.","Wrap the move command in a script that validates required flags per mode."],"tags":["missing-argument","token","move","cms"],"backgroundTag":"missing-required-argument","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"}