{"record":{"id":"99c2887e3d3ad25e","repo":"apache/cassandra","slug":"unexpected-parameter-s-must-be-s","errorCode":null,"errorMessage":"Unexpected parameter '%s', must be %s","messagePattern":"Unexpected parameter '(.+?)', must be (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/repair/autorepair/FixedSplitTokenRangeSplitter.java","lineNumber":142,"sourceCode":"            for (String tableName : tableNames)\n            {\n                long totalBytes = repairPlan.getTableEstimatedBytes(AutoRepairUtils.getKeyspaceTableName(keyspaceName, tableName));\n                long bytesPerRange = Math.max(1, totalBytes / splitsPerRange);\n                for (Range<Token> splitRange : allRanges)\n                {\n                    repairAssignments.add(new RepairAssignment(splitRange, keyspaceName, Collections.singletonList(tableName), bytesPerRange));\n                }\n            }\n        }\n        return new KeyspaceRepairAssignments(priority, keyspaceName, repairAssignments);\n    }\n\n    @Override\n    public void setParameter(String key, String value)\n    {\n        if (!key.equals(NUMBER_OF_SUBRANGES))\n        {\n            throw new IllegalArgumentException(\"Unexpected parameter '\" + key + \"', must be \" + NUMBER_OF_SUBRANGES);\n        }\n        logger.info(\"Setting {} to {} for repair type {}\", key, value, repairType);\n        this.numberOfSubranges = Integer.parseInt(value);\n    }\n\n    @Override\n    public Map<String, String> getParameters()\n    {\n        return Collections.singletonMap(NUMBER_OF_SUBRANGES, Integer.toString(numberOfSubranges));\n    }\n}\n","sourceCodeStart":124,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/repair/autorepair/FixedSplitTokenRangeSplitter.java#L124-L154","documentation":"FixedSplitTokenRangeSplitter.setParameter rejects any parameter key other than the constant NUMBER_OF_SUBRANGES with an IllegalArgumentException. This splitter supports exactly one configurable option.","triggerScenarios":"Dynamically updating auto-repair config (nodetool setautorepairconfig / config reload) with a key the FixedSplit splitter doesn't recognize, e.g. bytes_per_assignment or a misspelled number_of_subranges.","commonSituations":"Copy-pasting bytes-based parameters intended for RepairTokenRangeSplitter onto FixedSplitTokenRangeSplitter; typos like number_of_subrange; stale config carrying obsolete keys.","solutions":["Use only the 'number_of_subranges' key for FixedSplitTokenRangeSplitter","Switch to RepairTokenRangeSplitter if bytes-based parameters are needed","Correct the key spelling in the auto_repair config","Use nodetool getautorepairconfig to see current valid parameters"],"exampleFix":"// before\nsplitter.setParameter(\"bytes_per_assignment\", \"1GB\");\n// after\nsplitter.setParameter(\"number_of_subranges\", \"10\");","handlingStrategy":"validation","validationCode":"if (!\"number_of_subranges\".equals(key))\n    throw new IllegalArgumentException(\"FixedSplitTokenRangeSplitter only accepts number_of_subranges\");","typeGuard":null,"tryCatchPattern":"try { splitter.setParameter(key, value); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unexpected parameter\")) logger.warn(\"Invalid param {} for fixed splitter\", key);\n    else throw e;\n}","preventionTips":["Only send 'number_of_subranges' to FixedSplitTokenRangeSplitter","Reserve bytes-based params for RepairTokenRangeSplitter","Validate config keys against the splitter type before applying dynamic updates"],"tags":["autorepair","configuration","parameter-validation"],"backgroundTag":"invalid-config-value","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"}