Skip to content

[Bug] astrbot_file_read_tool 读取目录时返回误导性 "Permission denied" #9087

Description

@Fronut

What happened / 发生了什么

当 LLM 调用 astrbot_file_read_tool 并传入目录路径时,工具返回:

Error: [Errno 13] Permission denied: 'D:\Program Files\AstrBot\backend\app\astrbot\api'

错误信息暗示是权限不足,但实际原因是传入了一个目录而非文件。

Reproduce / 如何复现?

  1. 在 local 运行时模式下
  2. 调用 astrbot_file_read_toolpath 参数传入一个已存在的目录路径
  3. 例如:path = "D:\\Program Files\\AstrBot\\backend\\app\\astrbot\\api"

预期结果

返回清晰的错误提示,告知用户传入的是目录,而非文件。例如:

Error: `D:\Program Files\AstrBot\backend\app\astrbot\api` is a directory, not a file.
Use a file path instead, or use `astrbot_execute_shell` to list directory contents.

实际结果

Error: [Errno 13] Permission denied: 'D:\Program Files\AstrBot\backend\app\astrbot\api'

AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器

4.26.2 Windows

OS

Windows

Logs / 报错日志

ID:
call_00_qcNVP0TPbvMvHO5uD4PM9903
Args:
{
"path": "D:\Program Files\AstrBot\backend\app\astrbot\api"
}
Result:
Error: [Errno 13] Permission denied: 'D:\Program Files\AstrBot\backend\app\astrbot\api'

影响

  • LLM 被误导为权限问题,可能反复重试或要求用户提升权限,浪费 token 和时间
  • 实际应引导 LLM 使用正确路径或换用其他工具

根因分析

调用链如下:

FileReadTool.call()                          # fs.py line ~278
  → read_file_tool_result()                  # file_read_utils.py
    → _probe_local_file(path)                # file_read_utils.py
      → Path(path).open("rb")                # 目录不能以 rb 模式打开 → OSError(Errno 13)
        → 异常传播回 FileReadTool.call()
          → except PermissionError           # 被当作权限错误捕获
            → return f"Error: {exc}"         # 返回误导性信息

关键问题:

  1. _probe_local_file()file_read_utils.py)直接对路径执行 open("rb"),不做文件/目录区分
  2. Windows 下对目录执行 open() 返回 Errno 13(Permission denied),Linux 下返回 Errno 21(Is a directory)
  3. 异常在 FileReadTool.call() 中被 except PermissionError 捕获,统一当作权限错误展示
  4. 没有任何地方在文件 I/O 之前检查路径是否为目录

影响范围

  • astrbot/core/tools/computer_tools/fs.pyFileReadTool.call() 方法
  • astrbot/core/computer/file_read_utils.py_probe_local_file() 函数(间接涉及)
  • 仅影响 local runtime 模式;sandbox 模式的错误表现取决于 sandbox 实现
  • 不影响 astrbot_file_write_toolastrbot_file_edit_toolastrbot_grep_tool

建议修复

FileReadTool.call() 中,路径规范化完成后、实际文件 I/O 开始前,增加 os.path.isdir() 检查。这是最早的拦截点,对 local 和 sandbox 两种模式均有效。

Are you willing to submit a PR? / 你愿意提交 PR 吗?

  • Yes!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:coreThe bug / feature is about astrbot's core, backendbugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions