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
- Audit the TreeView construction code and ensure every end() has a matching preceding start().
- Track branch depth with a counter and only call end() when depth > 0.
- 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
- Maintain a depth counter that mirrors start/end calls.
- Wrap each branch in try/finally to guarantee a matching end().
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
- Arthas server port binding failed! Please check $HOME/logs/a
- can not getResources arthas-bin.zip from classloader: ${clas
- can not find arthas-core.jar under arthasHome: ${arthasHome}
- Arthas server port binding failed! Please check $HOME/logs/a
- Failed to create directory within ${TEMP_DIR_ATTEMPTS} attem
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/19169a944f1671be.
Report an issue: GitHub.