{"record":{"id":"7100c6230e07feab","repo":"oracle/graal","slug":"a-negative-probability-of-is-not-allowed","errorCode":null,"errorMessage":"A negative probability of {} is not allowed!","messagePattern":"A negative probability of (.+?) is not allowed!","errorType":"exception","errorClass":"GraalError","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/extended/SwitchNode.java","lineNumber":341,"sourceCode":"                succ = next;\n            }\n            assertTrue(succ.next() instanceof SwitchCaseProbabilityNode,\n                            \"Cannot inject switch probability, since key successor %s is not a SwitchCaseProbabilityNode\",\n                            succ.next());\n            SwitchCaseProbabilityNode caseProbabilityNode = (SwitchCaseProbabilityNode) succ.next();\n\n            ValueNode probabilityNode = caseProbabilityNode.getProbability();\n            if (!probabilityNode.isConstant()) {\n                /*\n                 * If any of the probabilities are not constant we bail out of simplification, which\n                 * will cause compilation to fail later during lowering since the node will be left\n                 * behind\n                 */\n                return;\n            }\n            double probabilityValue = probabilityNode.asJavaConstant().asDouble();\n            if (probabilityValue < 0.0) {\n                throw new GraalError(\"A negative probability of \" + probabilityValue + \" is not allowed!\");\n            } else if (probabilityValue > 1.0) {\n                throw new GraalError(\"A probability of more than 1.0 (\" + probabilityValue + \") is not allowed!\");\n            } else if (Double.isNaN(probabilityValue)) {\n                /*\n                 * We allow NaN if the node is in unreachable code that will eventually fall away,\n                 * or else an error will be thrown during lowering since we keep the node around.\n                 * See analogous case in BranchProbabilityNode.\n                 */\n                return;\n            }\n            nodeProbabilities[i] = probabilityValue / numKeysPerBlock[keySuccessorIndex(i)];\n        }\n\n        for (AbstractBeginNode blockSuccessor : successors) {\n            AbstractBeginNode succ = blockSuccessor;\n            while (succ.next() instanceof AbstractBeginNode next) {\n                succ = next;\n            }","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/extended/SwitchNode.java#L323-L359","documentation":"SwitchNode's simplification (SwitchNode.java:341) validates that every constant case probability attached to a switch node is in [0.0, 1.0]. This error means one CaseProbabilityNode evaluated to a constant double less than 0.0, which is meaningless as a branch probability. Graal throws it because downstream phases assume probabilities are valid ratios when distributing node probabilities over successors.","triggerScenarios":"Creating a switch with explicit case probabilities (SwitchNode.create(...) or IntegerSwitchNode constructor with a double[] probabilities argument) where at least one entry is a negative constant. The value is only checked when the probability node is constant during simplify().","commonSituations":"Hand-written snippets or test graphs that pass raw profile counts or differences instead of normalized ratios; a scaling/normalization bug in code that computes probabilities (e.g., subtracting weights can yield negatives).","solutions":["Fix the caller that builds the probabilities array so every entry is within [0.0, 1.0]","If the values are relative weights, normalize them by dividing by the total weight before passing them to SwitchNode.create","Add an assert in your code that validates the array before switch creation to catch the bug at the source"],"exampleFix":"// before\ndouble[] probs = {2.0, -1.0, 3.0};\nSwitchNode.create(..., probs, ...);\n\n// after\ndouble total = 6.0;\ndouble[] probs = {2.0 / total, 1.0 / total, 3.0 / total}; // all in [0,1]\nSwitchNode.create(..., probs, ...);","handlingStrategy":"validation","validationCode":"static double[] checkProbabilities(double[] probs) {\n    for (double p : probs) {\n        if (p < 0.0 || p > 1.0) throw new IllegalArgumentException(\"probability out of range: \" + p);\n    }\n    return probs;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always normalize probability arrays to sum to <= 1.0 before passing them to SwitchNode.create","Never feed raw profile counters into probability slots; convert counts to ratios first"],"tags":["graal","compiler","switch","branch-probability","validation"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}