{"record":{"id":"f4845dccadb525e7","repo":"apache/cassandra","slug":"invalid-specification","errorCode":null,"errorMessage":"Invalid specification: ","messagePattern":"Invalid specification: ","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tcm/transformations/AlterTopology.java","lineNumber":70,"sourceCode":"    public static final Serializer serializer = new Serializer();\n\n    private final Map<NodeId, Location> updates;\n    private final PlacementProvider placementProvider;\n\n    public AlterTopology(Map<NodeId, Location> updates, PlacementProvider placementProvider)\n    {\n        this.updates = updates;\n        this.placementProvider = placementProvider;\n    }\n\n    public static Map<NodeId, Location> parseArgs(String args, Directory directory)\n    {\n        Map<NodeId, Location> asMap = new HashMap<>();\n        for (String change : args.split(\",\"))\n        {\n            String[] parts = change.trim().split(\"=\");\n            if (parts.length != 2)\n                throw new IllegalArgumentException(\"Invalid specification: \" + change);\n\n            if (parts[0].isEmpty() || parts[1].isEmpty())\n                throw new IllegalArgumentException(\"Invalid specification: \" + change);\n\n            NodeId id = getNodeIdFromString(parts[0].trim(), directory);\n            if (asMap.containsKey(id))\n                throw new IllegalArgumentException(\"Multiple updates for node \" + id + \" (\" + parts[0].trim() + \" )\");\n            asMap.put(getNodeIdFromString(parts[0].trim(), directory), Location.fromString(parts[1].trim()));\n        }\n        return asMap;\n    }\n\n    private static NodeId getNodeIdFromString(String s, Directory directory)\n    {\n        // first try to parse the id as a node id, either in UUID or int form\n        try\n        {\n            return NodeId.fromString(s);","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tcm/transformations/AlterTopology.java#L52-L88","documentation":"AlterTopology.parseArgs parses a comma-separated list of nodeId=dc/rack specifications for topology changes. If a segment does not split into exactly two '=' separated non-empty parts, IllegalArgumentException 'Invalid specification' is thrown. This is strict input validation before any cluster change is committed.","triggerScenarios":"Calling AlterTopology.parseArgs (or the exposing tool/API) with a malformed change string such as 'a=b=c', 'nodewithnovalue', or empty '=' halves, e.g. 'id1=dc1,id2' or '=dc1'.","commonSituations":"Typo in nodetool/classictool topology arguments; shell quoting stripping the '=' side; copying examples with wrong format; whitespace/newline contamination in batch scripts.","solutions":["Correct the argument to 'nodeId=dc:rack' pairs separated by commas, e.g. 'id1=dc1:r1,id2=dc2:r2'","Quote the whole argument in the shell so '=' and ',' are not mangled","Check each segment contains exactly one '=' with non-empty id and location"],"exampleFix":"// before\nnodetool altertopology 'id1=dc1,id2'   // 'id2' has no =value\n// after\nnodetool altertopology 'id1=dc1:r1,id2=dc2:r2'","handlingStrategy":"validation","validationCode":"// validate each change segment before invoking\nfor (String seg : changes.split(\",\")) {\n    String[] parts = seg.trim().split(\"=\");\n    if (parts.length != 2 || parts[0].isEmpty() || parts[1].isEmpty())\n        throw new IllegalArgumentException(\"bad segment: \" + seg);\n}","typeGuard":null,"tryCatchPattern":"try { parseArgs(args, directory); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Invalid specification:\")) { /* show usage and the offending segment */ }\n    else throw e;\n}","preventionTips":["Follow the strict 'id=dc:rack' pair format, comma-separated","Quote topology arguments in shell scripts","Validate generated command strings before execution"],"tags":["cli","topology","argument-parsing"],"backgroundTag":"invalid-argument-format","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"}