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

  1. Pass -1 when you want all instances (no cap).
  2. Pass a positive int to cap the returned array length.
  3. 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

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


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/f8891158d4cc8fe1. Report an issue: GitHub.