alibaba/arthas · error · IllegalStateException

current node is root.

Error message

current node is root.

What it means

TreeView.end() throws IllegalStateException when the current node is the root node — meaning there is no open branch to close. TreeView builds a tree imperatively: start() opens a branch (descends), end() closes it (ascends to parent). Calling end() more times than start() at the top level underflows to the root, which has no parent.

Source

Thrown at core/src/main/java/com/taobao/arthas/core/view/TreeView.java:140

    public TreeView begin(String data) {
        Node n = current.find(data);
        if (n != null) {
            current = n;
        } else {
            current = new Node(current, data);
        }
        current.markBegin();
        return this;
    }

    /**
     * 结束一个分支节点
     *
     * @return this
     */
    public TreeView end() {
        if (current.isRoot()) {
            throw new IllegalStateException("current node is root.");
        }
        current.markEnd();
        current = current.parent;
        return this;
    }

    /**
     * 结束一个分支节点,并带上备注
     *
     * @return this
     */
    public TreeView end(String mark) {
        if (current.isRoot()) {
            throw new IllegalStateException("current node is root.");
        }
        current.markEnd().mark(mark);
        current = current.parent;
        return this;

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Audit the TreeView construction code and ensure every end() has a matching preceding start().
  2. Track branch depth with a counter and only call end() when depth > 0.
  3. Use try/finally around start()/end() pairs to guarantee balance even on early returns.

Example fix

// before: unbalanced — one extra end()
TreeView tv = new TreeView(true, "root");
tv.start("branch1").end().end(); // second end() throws

// after: balanced
treeView tv = new TreeView(true, "root");
tv.start("branch1").end();
Defensive patterns

Strategy: validation

Validate before calling

// Track depth to avoid over-calling end()
int depth = 0;
treeView.start("branch"); depth++;
// ... render ...
if (depth > 0) { treeView.end(); depth--; }

Try / catch

try {
    treeView.end();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("root")) {
        // already at root — nothing to close, ignore or log
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling treeView.end() when the number of end() calls has already matched the number of start() calls, returning current to the root, and one more end() is issued.

Common situations: A mismatched start()/end() pair in custom command rendering code; a loop that calls end() unconditionally; refactoring that removed a start() but left its end(); calling end() on a freshly constructed TreeView that only has a root.

Related errors


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