{"record":{"id":"d8038c08b48f109b","repo":"MyCATApache/Mycat-Server","slug":"some-slot-has-not-moved-to","errorCode":null,"errorMessage":"some slot has not moved to","messagePattern":"some slot has not moved to","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/migrate/MigrateUtils.java","lineNumber":77,"sourceCode":"                int hasSlots = getCurTotalSizeForTask(curRangeList);\n                int needMove = (i1 == 0) ? newSlotPerNode - hasSlots + gb : newSlotPerNode - hasSlots;\n                if (needMove > 0) {\n                    List<Range> moveList = getPartAndRemove(allMoveList, needMove);\n                    MigrateTask task = new MigrateTask();\n                    if (i >= oldDataNodes.size()) {\n                        throw new RuntimeException(String.format(\"crc32slot_%s.properties does not match schema table dataNode.\", table.toUpperCase()));\n                    }\n                    task.setFrom(oldDataNodes.get(i));\n                    task.setTo(newDataNode);\n                    task.setTable(table);\n                    task.setSlots(moveList);\n                    curRangeList.add(task);\n                    newNodeTask.put(newDataNode, curRangeList);\n                }\n            }\n\n            if (allMoveList.size() > 0) {\n                throw new RuntimeException(\"some slot has not moved to\");\n            }\n        }\n        return newNodeTask;\n    }\n\n\n    private static List<Range> getPartAndRemove(List<Range> rangeList, int size) {\n        List<Range> result = new ArrayList<>();\n\n        for (int i = 0; i < rangeList.size(); i++) {\n\n            Range range = rangeList.get(i);\n            if (range == null)\n                continue;\n            if (range.size == size) {\n                result.add(new Range(range.start, range.end));\n                rangeList.set(i, null);\n                break;","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/migrate/MigrateUtils.java#L59-L95","documentation":"After distributing slots to new nodes, balanceExpand verifies that allMoveList is drained; leftovers mean the algorithm could not place every slot that must move. It throws 'some slot has not moved to' to prevent an inconsistent slot map from being persisted.","triggerScenarios":"needMove computations leave slots unassigned because old/new dataNode lists or newSlotPerNode arithmetic do not cover allMoveList; duplicate or overlapping dataNodes in the new list; gb (granularity/backlog) value produces negative transfer amounts.","commonSituations":"Scaling out with new nodes whose count or capacity doesn't match the slot math; malformed crc32slot rule file producing extra ranges; running expansion twice with partially applied state.","solutions":["Check that new dataNode count times newSlotPerNode covers total slots; adjust node count or the expansion plan.","Validate the crc32slot rule file ranges are contiguous and non-overlapping before expansion.","Recalculate the expansion from the original rule file (regenerate it) instead of reusing a partially migrated state.","If reproducible, log allMoveList contents and file a report with the rule file and schema.xml."],"exampleFix":"// before\nif (allMoveList.size() > 0) {\n    throw new RuntimeException(\"some slot has not moved to\");\n}\n// after\nif (allMoveList.size() > 0) {\n    throw new RuntimeException(\"some slot has not moved to, \" + allMoveList.size()\n        + \" slots remain: \" + allMoveList);\n}","handlingStrategy":"validation","validationCode":"// pre-check slot math\nint totalSlots = getTotalSlots(ruleFile);\nint nodes = newDataNodes.size();\nif (totalSlots % nodes != 0) log.warn(\"slots won't divide evenly across \" + nodes + \" nodes\");\nif (newDataNodes.size() < 1) throw new IllegalStateException(\"need at least one target node\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run expansion from a freshly regenerated rule file","Ensure new dataNode list has no duplicates","Plan node counts so slot redistribution covers allMoveList completely","Dry-run balanceExpand and inspect resulting tasks before applying"],"tags":["migration","sharding","slot-allocation","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}