alibaba/arthas · error · IllegalArgumentException
cursor 解析失败: ${e.getMessage()}
Error message
cursor 解析失败: ${e.getMessage()} What it means
Thrown by decodeCursor() in the ViewFile MCP tool as the outer catch wrapping any inner IllegalArgumentException (the missing path/missing offset/negative offset cases, errors 95-97). It can also surface for a cursor that fails base64url decoding or JSON parsing, since the inner operations can throw. The message appends the specific inner reason.
Source
Thrown at core/src/main/java/com/taobao/arthas/core/mcp/tool/function/basic1000/ViewFileTool.java:159
byte[] jsonBytes = Base64.getUrlDecoder().decode(cursor);
String json = new String(jsonBytes, StandardCharsets.UTF_8);
Map<String, Object> map = JsonParser.fromJson(json, new TypeReference<Map<String, Object>>() {});
Object pathObj = map.get("path");
Object offsetObj = map.get("offset");
if (!(pathObj instanceof String) || ((String) pathObj).trim().isEmpty()) {
throw new IllegalArgumentException("cursor 缺少 path");
}
if (!(offsetObj instanceof Number)) {
throw new IllegalArgumentException("cursor 缺少 offset");
}
long offset = ((Number) offsetObj).longValue();
if (offset < 0) {
throw new IllegalArgumentException("cursor offset 不允许为负数");
}
return new CursorValue(((String) pathObj).trim(), offset);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("cursor 解析失败: " + e.getMessage(), e);
}
}
private String encodeCursor(String path, long offset) {
Map<String, Object> cursor = new LinkedHashMap<>();
cursor.put("v", 1);
cursor.put("path", path);
cursor.put("offset", offset);
String json = JsonParser.toJson(cursor);
return Base64.getUrlEncoder().withoutPadding().encodeToString(json.getBytes(StandardCharsets.UTF_8));
}
private List<Path> loadAllowedRoots() {
String config = System.getenv(ALLOWED_DIRS_ENV);
List<Path> roots = new ArrayList<>();
if (config != null && !config.trim().isEmpty()) {
String[] parts = config.split(",");View on GitHub (pinned to 21cf2e9ba5)
Solutions
- Discard the bad cursor and call viewfile with an explicit `path` (+ offset) to start fresh, then use the newly returned cursor.
- Ensure the cursor is the exact base64url string returned by a prior viewfile response, unmodified.
- If you must build a cursor, encode JSON {"v":1,"path":<non-empty string>,"offset":<non-negative number>} with URL-safe base64, no padding.
Example fix
// before viewfile(cursor="not-a-valid-cursor") // after viewfile(path="/var/log/app.log", offset=0) // get a fresh cursor, then reuse it
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate a cursor before sending it: decode + check shape
static boolean isValidCursor(String cursor) {
try {
String json = new String(Base64.getUrlDecoder().decode(cursor), StandardCharsets.UTF_8);
Map<String,Object> m = JsonParser.fromJson(json, new TypeReference<Map<String,Object>>(){});
return m.get("path") instanceof String && !((String)m.get("path")).trim().isEmpty()
&& m.get("offset") instanceof Number && ((Number)m.get("offset")).longValue() >= 0;
} catch (Exception e) { return false; }
} Type guard
null
Try / catch
try {
viewfile(cursor);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("cursor 解析失败")) {
// discard the bad cursor, fall back to a fresh path-based call
viewfile(path, 0L);
} else throw e;
} Prevention
- Treat cursors as opaque tokens returned by the server; do not hand-edit them.
- On any cursor failure, restart with an explicit path call to obtain a fresh cursor.
- If building cursors, validate base64url + JSON shape + required non-negative numeric offset before use.
When it happens
Trigger: Calling viewfile with any malformed cursor: not valid base64url, not valid JSON, or valid JSON missing required fields / with a negative offset. Any IllegalArgumentException inside the try block is rethrown with prefix 'cursor 解析失败:'.
Common situations: Using a stale/corrupted/truncated cursor token; passing a non-cursor string into the cursor field; client-side encoding bug; manually edited cursor.
Related errors
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/d3049f115f8ec6e4.
Report an issue: GitHub.