{"record":{"id":"0aa6328eb7c870ea","repo":"nathanmarz/storm","slug":"cannot-have-one-group-have-fixed-parallelism-of-two","errorCode":null,"errorMessage":"Cannot have one group have fixed parallelism of two different values","messagePattern":"Cannot have one group have fixed parallelism of two different values","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"storm-core/src/jvm/storm/trident/TridentTopology.java","lineNumber":655,"sourceCode":"    \n    private static Map getSpoutComponentConfig(Object spout) {\n        if(spout instanceof IRichSpout) {\n            return ((IRichSpout) spout).getComponentConfiguration();\n        } else if (spout instanceof IBatchSpout) {\n            return ((IBatchSpout) spout).getComponentConfiguration();\n        } else {\n            return ((ITridentSpout) spout).getComponentConfiguration();\n        }\n    }\n    \n    private static Integer getFixedParallelism(Set<Group> groups) {\n        Integer ret = null;\n        for(Group g: groups) {\n            for(Node n: g.nodes) {\n                if(n.stateInfo != null && n.stateInfo.spec.requiredNumPartitions!=null) {\n                    int reqPartitions = n.stateInfo.spec.requiredNumPartitions;\n                    if(ret!=null && ret!=reqPartitions) {\n                        throw new RuntimeException(\"Cannot have one group have fixed parallelism of two different values\");\n                    }\n                    ret = reqPartitions;\n                }\n            }\n        }\n        return ret;\n    }\n    \n    private static boolean isIdentityPartition(PartitionNode n) {\n        Grouping g = n.thriftGrouping;\n        if(g.is_set_custom_serialized()) {\n            CustomStreamGrouping csg = (CustomStreamGrouping) Utils.deserialize(g.get_custom_serialized());\n            return csg instanceof IdentityGrouping;\n        }\n        return false;\n    }\n    \n    private static void addEdge(DirectedGraph g, Object source, Object target, int index) {","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/storm/trident/TridentTopology.java#L637-L673","documentation":"getFixedParallelism derives a group's fixed parallelism from the requiredNumPartitions of state specs in its nodes. If two different states in the same group require different partition counts, a single parallelism cannot satisfy both, so this RuntimeException is thrown during build.","triggerScenarios":"A TridentTopology with multiple persistentAggregates/states (e.g. two HBase or Redis map states with different requiredNumPartitions) whose nodes fall into the same parallelism-equivalence group.","commonSituations":"Several persistentAggregates downstream of a shared partitionBy/groupBy without explicit parallelismHints; migrating one state backend and adding a second with different partition requirements; merging two topology fragments into one TridentTopology.","solutions":["Set explicit, equal requiredNumPartitions on all state specs in the group","Add explicit parallelismHints and reorder/partition so the states are not in the same equivalence group","Give each state its own branch partitioned independently instead of sharing a group"],"exampleFix":"// before\nHBaseState.Options o1 = new HBaseState.Options().setNumPartitions(4);\nHBaseState.Options o2 = new HBaseState.Options().setNumPartitions(8); // same group\n// after\nHBaseState.Options o2 = new HBaseState.Options().setNumPartitions(4); // match required partitions","handlingStrategy":"validation","validationCode":"// all states in a shared group must declare the same requiredNumPartitions\nSet<Integer> reqs = states.stream().map(s -> s.getRequiredNumPartitions()).collect(Collectors.toSet());\nif (reqs.size() > 1) throw new IllegalArgumentException(\"All co-grouped states must require the same partitions: \" + reqs);","typeGuard":null,"tryCatchPattern":"try {\n    topology.build();\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"fixed parallelism of two different values\")) {\n        throw new IllegalStateException(\"Unify requiredNumPartitions across states in the same group\", e);\n    } throw e;\n}","preventionTips":["Use one shared constant for requiredNumPartitions across state specs","Partition states into separate branches when partition requirements differ","Build the topology in tests to surface the conflict pre-deploy"],"tags":["storm","trident","parallelism","state"],"backgroundTag":"internal-invariant-violation","analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}