{"record":{"id":"f8891158d4cc8fe1","repo":"alibaba/arthas","slug":"limit-can-not-be-0","errorCode":null,"errorMessage":"limit can not be 0","messagePattern":"limit can not be 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"arthas-vmtool/src/main/java/arthas/VmTool.java","lineNumber":104,"sourceCode":"    public void interruptSpecialThread(int threadId) {\n        Map<Thread, StackTraceElement[]> allThread = Thread.getAllStackTraces();\n        for (Map.Entry<Thread, StackTraceElement[]> entry : allThread.entrySet()) {\n            if (entry.getKey().getId() == threadId) {\n                entry.getKey().interrupt();\n                return;\n            }\n        }\n    }\n\n    @Override\n    public <T> T[] getInstances(Class<T> klass) {\n        return getInstances0(klass, -1);\n    }\n\n    @Override\n    public <T> T[] getInstances(Class<T> klass, int limit) {\n        if (limit == 0) {\n            throw new IllegalArgumentException(\"limit can not be 0\");\n        }\n        return getInstances0(klass, limit);\n    }\n\n    @Override\n    public long sumInstanceSize(Class<?> klass) {\n        return sumInstanceSize0(klass);\n    }\n\n    @Override\n    public long getInstanceSize(Object instance) {\n        return getInstanceSize0(instance);\n    }\n\n    @Override\n    public long countInstances(Class<?> klass) {\n        return countInstances0(klass);\n    }","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/arthas-vmtool/src/main/java/arthas/VmTool.java#L86-L122","documentation":"VmTool.getInstances(Class, int limit) explicitly rejects limit == 0 with IllegalArgumentException. The sentinel for 'no limit' is -1 (used by the single-arg getInstances overload which calls getInstances0(klass, -1)). A positive limit caps the returned instance array size.","triggerScenarios":"Calling getInstances(klass, 0) — typically a caller computing a limit that resolves to zero (e.g. result of a subtraction, an uninitialized default, or a 'disabled' flag mapped to 0).","commonSituations":"Off-by-one in a paging/limit calculation; passing an unconfigured 'maxInstances' option that defaults to 0; confusion where 0 was assumed to mean 'unlimited'.","solutions":["Pass -1 when you want all instances (no cap).","Pass a positive int to cap the returned array length.","Guard upstream: if computedLimit == 0, substitute -1 or a sensible default."],"exampleFix":"// before\nT[] inst = vmTool.getInstances(klass, userLimit);  // userLimit == 0 -> throws\n\n// after\nint limit = userLimit <= 0 ? -1 : userLimit;\nT[] inst = vmTool.getInstances(klass, limit);","handlingStrategy":"validation","validationCode":"int safeLimit = (limit == 0) ? -1 : limit; // -1 = unlimited sentinel","typeGuard":"static boolean isValidInstanceLimit(int n) {\n    return n == -1 || n > 0;\n}","tryCatchPattern":"try {\n    return vmTool.getInstances(klass, limit);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"limit can not be 0\")) {\n        return vmTool.getInstances(klass, -1);\n    }\n    throw e;\n}","preventionTips":["Treat 0 as 'unintended' and substitute -1 (unlimited) or a positive default.","Document the -1 sentinel in any wrapper API.","Clamp user-supplied limits to the valid set {-1} ∪ positive ints."],"tags":["vmtool","validation","jvm","argument"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}