alibaba/arthas · error · IllegalArgumentException

不是普通文件: ${file}

Error message

不是普通文件: ${file}

What it means

Thrown by assertRegularFile when Files.isRegularFile(file) returns false. This catches directories, symlinks pointing to directories, device files, named pipes, and sockets. The check runs after the allowed-root verification, so only paths that already passed the whitelist are tested.

Source

Thrown at core/src/main/java/com/taobao/arthas/core/mcp/tool/function/basic1000/ViewFileTool.java:258

            if (!candidate.startsWith(root)) {
                continue;
            }
            if (!Files.exists(candidate)) {
                continue;
            }
            Path real = candidate.toRealPath();
            if (!real.startsWith(root)) {
                continue;
            }
            assertRegularFile(real);
            return real;
        }
        throw new IllegalArgumentException("文件不存在或不在允许目录白名单内: " + requestedPath);
    }

    private static void assertRegularFile(Path file) {
        if (!Files.isRegularFile(file)) {
            throw new IllegalArgumentException("不是普通文件: " + file);
        }
    }

    private static boolean isUnderAllowedRoot(Path file, List<Path> allowedRoots) {
        for (Path root : allowedRoots) {
            if (file.startsWith(root)) {
                return true;
            }
        }
        return false;
    }

    private static int clampMaxBytes(Integer maxBytes) {
        int value = (maxBytes != null && maxBytes > 0) ? maxBytes : DEFAULT_MAX_BYTES;
        return Math.min(value, MAX_MAX_BYTES);
    }

    private static long adjustOffset(boolean cursorUsed, long requestedOffset, long fileSize) {

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Point to a specific file, not a directory or folder path.
  2. Remove any trailing slash or path separator from the path argument.
  3. If using a cursor, ensure the original path was a regular file.

Example fix

// before
viewfile(path="/home/user/logs/")
// after
viewfile(path="/home/user/logs/app.log")
Defensive patterns

Strategy: validation

Validate before calling

// Before calling viewfile, check the path is a regular file
Path p = Paths.get(requestedPath);
if (!Files.isRegularFile(p)) {
    throw new IllegalStateException("Not a regular file: " + requestedPath);
}

Try / catch

try {
    Path file = resolveAllowedFile(path, allowedRoots);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("不是普通文件")) {
        // path resolved to a directory or special file
    }
}

Prevention

When it happens

Trigger: Calling viewfile with a path that resolves to a directory (e.g. the arthas-output directory itself), a symlink whose target is a directory, or a special file under an allowed root. Can be hit from both the absolute-path branch (line 231) and the relative-path branch (line 250).

Common situations: User accidentally passes a directory path instead of a file; path has a trailing slash; the cursor from a previous call encoded a directory path.

Related errors


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