alibaba/arthas · error · IllegalArgumentException

vmtool ${normalizedAction} 需要指定类名 (className)

Error message

vmtool ${normalizedAction} 需要指定类名 (className)

What it means

For the getInstances and referenceAnalyze actions, a fully-qualified className is mandatory because Arthas needs to know which class to search for live instances or analyze object references. Without it the underlying vmtool --action command would be meaningless.

Source

Thrown at core/src/main/java/com/taobao/arthas/core/mcp/tool/function/jvm300/VMToolTool.java:61

            ToolContext toolContext
    ) {
        StringBuilder cmd = buildCommand("vmtool");

        if (action == null || action.trim().isEmpty()) {
            throw new IllegalArgumentException("vmtool: action 参数不能为空");
        }
        String normalizedAction = action.trim();
        cmd.append(" --action ").append(normalizedAction);

        if (classLoaderHash != null && !classLoaderHash.trim().isEmpty()) {
            addParameter(cmd, "-c", classLoaderHash);
        } else if (classLoaderClass != null && !classLoaderClass.trim().isEmpty()) {
            addParameter(cmd, "--classLoaderClass", classLoaderClass);
        }

        if (ACTION_GET_INSTANCES.equals(normalizedAction) || ACTION_REFERENCE_ANALYZE.equals(normalizedAction)) {
            if (className == null || className.trim().isEmpty()) {
                throw new IllegalArgumentException("vmtool " + normalizedAction + " 需要指定类名 (className)");
            }
            addParameter(cmd, "--className", className);
        }

        if (ACTION_GET_INSTANCES.equals(normalizedAction)) {
            if (limit != null) {
                cmd.append(" --limit ").append(limit);
            }
            if (expandLevel != null && expandLevel > 0) {
                cmd.append(" -x ").append(expandLevel);
            }
            if (express != null && !express.trim().isEmpty()) {
                addParameter(cmd, "--express", express);
            }
        }

        if (ACTION_INTERRUPT_THREAD.equals(normalizedAction)) {
            if (threadId != null && threadId > 0) {

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Provide className as a fully-qualified Java class name (e.g., com.example.MyService or java.lang.String).
  2. Double-check that the action you chose (getInstances/referenceAnalyze) actually requires className.
  3. Ensure className is not whitespace-only.

Example fix

// before
vmtool(action="getInstances")
// after
vmtool(action="getInstances", className="java.util.HashMap")
Defensive patterns

Strategy: validation

Validate before calling

// Before calling vmtool with getInstances/referenceAnalyze, validate className
if (("getInstances".equals(action) || "referenceAnalyze".equals(action))
        && (className == null || className.trim().isEmpty())) {
    throw new IllegalArgumentException("className is required for " + action);
}

Try / catch

try {
    String result = vmtool(action, ..., className, ...);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("className")) {
        // className was missing for getInstances/referenceAnalyze
    }
}

Prevention

When it happens

Trigger: Calling vmtool with action=getInstances or action=referenceAnalyze while omitting className or passing a blank value. The check at line 59-62 runs after classLoaderHash/classLoaderClass processing.

Common situations: User forgets className assuming the tool infers it from context; passes an empty string; MCP client drops the field.

Related errors


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