alibaba/arthas · error · IllegalArgumentException
limit can not be 0
Error message
limit can not be 0
What it means
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.
Source
Thrown at arthas-vmtool/src/main/java/arthas/VmTool.java:104
public void interruptSpecialThread(int threadId) {
Map<Thread, StackTraceElement[]> allThread = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> entry : allThread.entrySet()) {
if (entry.getKey().getId() == threadId) {
entry.getKey().interrupt();
return;
}
}
}
@Override
public <T> T[] getInstances(Class<T> klass) {
return getInstances0(klass, -1);
}
@Override
public <T> T[] getInstances(Class<T> klass, int limit) {
if (limit == 0) {
throw new IllegalArgumentException("limit can not be 0");
}
return getInstances0(klass, limit);
}
@Override
public long sumInstanceSize(Class<?> klass) {
return sumInstanceSize0(klass);
}
@Override
public long getInstanceSize(Object instance) {
return getInstanceSize0(instance);
}
@Override
public long countInstances(Class<?> klass) {
return countInstances0(klass);
}View on GitHub (pinned to 21cf2e9ba5)
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.
Example fix
// before T[] inst = vmTool.getInstances(klass, userLimit); // userLimit == 0 -> throws // after int limit = userLimit <= 0 ? -1 : userLimit; T[] inst = vmTool.getInstances(klass, limit);
Defensive patterns
Strategy: validation
Validate before calling
int safeLimit = (limit == 0) ? -1 : limit; // -1 = unlimited sentinel
Type guard
static boolean isValidInstanceLimit(int n) {
return n == -1 || n > 0;
} Try / catch
try {
return vmTool.getInstances(klass, limit);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("limit can not be 0")) {
return vmTool.getInstances(klass, -1);
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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'.
Related errors
- backtraceNum must be -1 or greater
- vmtool: action 参数不能为空
- vmtool ${normalizedAction} 需要指定类名 (className)
- vmtool interruptThread 需要指定线程 ID (threadId)
- Required parameter '{}' is missing
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/f8891158d4cc8fe1.
Report an issue: GitHub.