{"record":{"id":"b780e46cd39b38f8","repo":"skylot/jadx","slug":"type-inference-error-updates-count-limit-reached","errorCode":null,"errorMessage":"Type inference error: updates count limit reached with updateSeq = {}. Try increasing type updates limit count.","messagePattern":"Type inference error: updates count limit reached with updateSeq = (.+?)\\. Try increasing type updates limit count\\.","errorType":"exception","errorClass":"JadxOverflowException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeUpdateInfo.java","lineNumber":61,"sourceCode":"\t}\n\n\tpublic @Nullable TypeUpdateRequest pollNextRequest() {\n\t\treturn ListUtils.removeLast(queue);\n\t}\n\n\tpublic @Nullable TypeUpdateRequest pollNextCallback() {\n\t\treturn ListUtils.removeLast(callbackQueue);\n\t}\n\n\tpublic void requestUpdate(InsnArg arg, ArgType changeType) {\n\t\tTypeUpdateEntry prev = updateMap.put(arg, new TypeUpdateEntry(updateSeq++, arg, changeType));\n\t\tif (prev != null) {\n\t\t\tthrow new JadxRuntimeException(\"Unexpected type update override for arg: \" + arg\n\t\t\t\t\t+ \" types: prev=\" + prev.getType() + \", new=\" + changeType\n\t\t\t\t\t+ \", insn: \" + arg.getParentInsn());\n\t\t}\n\t\tif (updateSeq > updatesLimitCount) {\n\t\t\tthrow new JadxOverflowException(\"Type inference error: updates count limit reached\"\n\t\t\t\t\t+ \" with updateSeq = \" + updateSeq + \". Try increasing type updates limit count.\");\n\t\t}\n\t\tif (updateSeq % 100 == 0) {\n\t\t\t// check for interruption sometimes (every update is too often)\n\t\t\tUtils.checkThreadInterrupt();\n\t\t}\n\t}\n\n\tpublic void rollbackUpdate(InsnArg arg) {\n\t\tTypeUpdateEntry removed = updateMap.remove(arg);\n\t\tif (removed != null) {\n\t\t\tint seq = removed.getSeq();\n\t\t\tupdateMap.values().removeIf(upd -> upd.getSeq() > seq);\n\t\t}\n\t}\n\n\tpublic void applyUpdates() {\n\t\tupdateMap.values().stream().sorted()","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeUpdateInfo.java#L43-L79","documentation":"Thrown by TypeUpdateInfo.requestUpdate when the running type-inference sequence number exceeds updatesLimitCount (= mth.getInsnsCount() * args.getTypeUpdatesLimitCount(), default multiplier 10). It bounds the work spent propagating types for one method so inference cannot loop forever. Unlike most errors here, this limit is user-tunable via JadxArgs.setTypeUpdatesLimitCount (CLI flag, GUI preference, or API setter).","triggerScenarios":"Type inference for a method needs more than (insnCount * typeUpdatesLimitCount) ArgType update requests, which happens when a candidate type fans out through many related args (generics, casts, ternary merges, overloaded method resolution). The message explicitly suggests raising the limit.","commonSituations":"Methods that use generics heavily, reflection/MethodHandle code, complex ternary chains, or code that mixes primitive/object arithmetic. Lowering typeUpdatesLimitCount below 10 (e.g. for speed) makes this much more likely; the default 10 is enough for normal code.","solutions":["Increase the multiplier: args.setTypeUpdatesLimitCount(20) (or higher) in the API, set typeUpdatesCountLimit in GUI preferences, or the matching CLI option.","Ensure you did not accidentally set the multiplier to a tiny value; default is 10 and Math.max(1, value) is enforced.","If it still overflows at very high values, report the method - it indicates oscillating type propagation that should be fixed upstream.","Catch JadxOverflowException per method so inference failure degrades gracefully (the method gets a warn comment, the run continues)."],"exampleFix":"// before\nJadxArgs args = new JadxArgs();\nargs.setInputFiles(files);\n// after\nJadxArgs args = new JadxArgs();\nargs.setInputFiles(files);\nargs.setTypeUpdatesLimitCount(50); // raise from default 10","handlingStrategy":"validation","validationCode":"// raise the limit up front if you decompile type-heavy code\nJadxArgs args = new JadxArgs();\nargs.setInputFiles(files);\nargs.setTypeUpdatesLimitCount(50); // default 10","typeGuard":null,"tryCatchPattern":"try {\n    typeUpdate.apply(mth, ssaVar, candidate);\n} catch (JadxOverflowException e) {\n    if (e.getMessage().contains(\"updates count limit reached\")) {\n        mth.addWarnComment(\"type inference hit updates limit for \" + ssaVar);\n    } else { throw e; }\n}","preventionTips":["Pre-set args.setTypeUpdatesLimitCount to 20-50 for generic-heavy inputs.","Never set it below 1 (enforced by Math.max); tiny values cause this error.","Catch JadxOverflowException per method so inference failure degrades to a warn comment."],"tags":["decompiler","type-inference","configurable-limit","generics","tunable"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}