{"record":{"id":"b67ec5c31c1e2d72","repo":"oracle/graal","slug":"deopt-taken-too-many-times","errorCode":null,"errorMessage":"deopt taken too many times: {} {}","messagePattern":"deopt taken too many times: (.+?) (.+?)","errorType":"exception","errorClass":"TooManyDeoptimizationsError","httpStatus":null,"severity":"critical","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ForceDeoptSpeculationPhase.java","lineNumber":150,"sourceCode":"        for (int i = 0; i < getMaximumDeoptCount(graph); i++) {\n            SpeculationLog.SpeculationReason reason = VERIFY_SPECULATION.createSpeculationReason(signature.getSignature(), signature.getId(deopt), i);\n            if (graph.getSpeculationLog().maySpeculate(reason)) {\n                return graph.getSpeculationLog().speculate(reason);\n            }\n        }\n        throw reportTooManySpeculationFailures(deopt);\n    }\n\n    @SuppressWarnings(\"unused\")\n    protected int getMaximumDeoptCount(StructuredGraph graph) {\n        return recompileCount;\n    }\n\n    /**\n     * Report a deopt cycle.\n     */\n    protected GraalError reportTooManySpeculationFailures(ValueNode deopt) {\n        throw new TooManyDeoptimizationsError(\"deopt taken too many times: \" + deopt + \" \" + getDeoptSummary(deopt.graph().getProfilingInfo()));\n    }\n}\n","sourceCodeStart":132,"sourceCodeEnd":153,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ForceDeoptSpeculationPhase.java#L132-L153","documentation":"ForceDeoptSpeculationPhase exists to detect deoptimization loops: when a forced deopt (ForceDeoptValueNode, enabled by the -Dgraal.Deoptimize* testing options) fires again on recompiled code, the speculation fails and the graph is recompiled without it. After getMaximumDeoptCount() failures the phase throws TooManyDeoptimizationsError (ForceDeoptSpeculationPhase.java:150) to break the cycle.","triggerScenarios":"Compiling with a force-deopt testing option (e.g., -Dgraal.DeoptimizeALot, DeoptimizeMethodFilter/DeoptimizeOnly, or playground-style deopt injection) where the marked code keeps deoptimizing across recompilations until the recompile budget is exhausted.","commonSituations":"Stress-testing configurations left enabled in benchmarks; a method filter that keeps matching hot methods whose deopts never stabilize; intentionally cyclic deopt tests that exceed the configured maximum.","solutions":["Remove or narrow the -Dgraal.Deoptimize* option so the affected method is no longer forced to deopt","If this is an intentional stress test, accept the error or raise the recompile/deopt budget option used by getMaximumDeoptCount","Check DeoptimizeMethodFilter/DeoptimizeOnly filters for a pattern that unintentionally matches the failing method"],"exampleFix":"# before\njava -Dgraal.DeoptimizeALot=true MyApp\n\n# after\njava -Dgraal.DeoptimizeALot=true -Dgraal.DeoptimizeOnly=com.foo.StableBench.myApp MyApp","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// when programmatically compiling with force-deopt options\ntry {\n    compiled = compile(options);\n} catch (TooManyDeoptimizationsError e) {\n    // deopt cycle confirmed: drop the force-deopt option and recompile\n    options = optionsWithout(DeoptimizeOptions);\n    compiled = compile(options);\n}","preventionTips":["Scope -Dgraal.Deoptimize* stress options with DeoptimizeOnly/DeoptimizeMethodFilter to stable methods","Treat this error in tests as the expected termination of a deopt-loop experiment, not a crash"],"tags":["graal","deoptimization","testing-options","stress"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}