Skip to content

fix(preprocess): handle Windows path_mapping rules without crashing#8875

Open
he-yufeng wants to merge 1 commit into
AstrBotDevs:masterfrom
he-yufeng:fix/preprocess-path-mapping-multicolon
Open

fix(preprocess): handle Windows path_mapping rules without crashing#8875
he-yufeng wants to merge 1 commit into
AstrBotDevs:masterfrom
he-yufeng:fix/preprocess-path-mapping-multicolon

Conversation

@he-yufeng

@he-yufeng he-yufeng commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

问题

PreProcessStage 在做媒体路径映射时,对每条 path_mapping 规则用了 from_, to_ = mapping.split(":")。这假设规则里恰好有一个冒号,但实际上:

  • Windows 盘符规则(如 C:/remote:D:/local)会被切成 4 段 → ValueError: too many values to unpack (expected 2)
  • 漏写冒号的规则(如 badmapping)→ ValueError: not enough values to unpack

任何配置了 path_mapping 的 Windows 部署,只要收到带图片/语音的消息,preprocess stage 就会在这一行崩掉,整个 pipeline 中断。

修复

直接复用已有的 astrbot.core.utils.path_util.path_Mapping——它已经正确处理 Windows 盘符、Linux 路径和格式错误的规则(多余/缺失冒号时告警跳过而非抛异常),而且 respond stage 早就在用它。preprocess stage 改成调用同一个 helper,行为与之前的单冒号场景一致,同时不再崩溃。

验证

python -m pytest tests/test_preprocess_stage.py

新增 test_preprocess_path_mapping_tolerates_multi_colon_rules 覆盖带盘符冒号的规则;回退本次改动时该用例(以及已有的 test_preprocess_path_mapping_accepts_file_uri 在 Windows 上)会以 too many values to unpack 失败,修复后全部通过。ruff checkruff format --check 均通过。

Summary by Sourcery

Fix media URL path mapping in the preprocess stage to safely handle Windows-style and malformed path_mapping rules without crashing.

Bug Fixes:

  • Prevent preprocess media path mapping from raising unpacking errors when path_mapping rules contain multiple or missing colons, such as Windows drive-letter mappings.

Tests:

  • Add a regression test ensuring the preprocess stage tolerates Windows-style multi-colon path_mapping rules without failing.

The preprocess stage split each path_mapping rule on a bare ":", which
raises "too many values to unpack" for Windows drive-letter rules
(e.g. "C:/a:D:/b") and "not enough values" for rules without a colon.
Delegate to path_Mapping, which already handles Windows/Linux/malformed
rules and is the helper the respond stage already uses.
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend labels Jun 18, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the path mapping logic in the preprocessing stage to use the path_Mapping utility, preventing crashes on Windows-style drive-letter rules, and adds a test case to verify this behavior. The reviewer pointed out a critical issue in the imported path_Mapping function: it uses os.path.exists to detect Windows paths, which fails in Docker or cross-platform environments where the remote path does not exist locally. A robust alternative checking for drive-letter patterns was suggested to resolve this limitation.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

# Delegate to path_Mapping so Windows drive-letter rules
# (e.g. "C:/a:D:/b") and malformed rules are handled instead
# of crashing on a bare ":" split, matching the respond stage.
component.url = path_Mapping(mappings, component.url)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

⚠️ path_Mapping 存在严重逻辑缺陷,导致 Windows 路径映射在大多数情况下失效

虽然此 PR 成功避免了 preprocess_stage 崩溃,但直接复用的 path_Mapping(位于 astrbot/core/utils/path_util.py)内部存在一个严重的逻辑缺陷:

path_util.py 中,它使用 os.path.exists(rule[0] + ":" + rule[1]) 来判断规则是否为 Windows 路径。

  • 如果是在 Linux/Docker 环境下运行,或者在 Windows 上但该远程路径(如 C:/remote)在本地并不实际存在,os.path.exists 将返回 False
  • 这会导致像 C:/remote:D:/local 这样包含 4 个部分的规则落入 else 分支,被误判为“格式错误”并直接跳过(伴随一条警告日志)。

由于路径映射的初衷通常就是将本地不存在的远程路径映射为本地存在的路径,这一限制导致该功能在跨平台或容器化部署时几乎完全失效。

💡 建议修复方案

建议修改 astrbot/core/utils/path_util.py 中的 path_Mapping 函数,通过判断首个分段是否为单个英文字母(Windows 盘符)来识别 Windows 路径,而不是依赖 os.path.exists

def path_Mapping(mappings, srcPath: str) -> str:
    for mapping in mappings:
        rule = mapping.split(":")
        if len(rule) == 2:
            from_, to_ = mapping.split(":")
        elif len(rule) > 4 or len(rule) == 1:
            logger.warning(f"路径映射规则错误: {mapping}")
            continue
        # 通过盘符特征(单字母且为字母)判断,不依赖本地文件是否存在
        elif len(rule[0]) == 1 and rule[0].isalpha():
            from_ = rule[0] + ":" + rule[1]
            if len(rule) == 3:
                to_ = rule[2]
            else:
                to_ = rule[2] + ":" + rule[3]
        else:
            from_ = rule[0]
            if len(rule) == 3:
                to_ = rule[1] + ":" + rule[2]
            else:
                logger.warning(f"路径映射规则错误: {mapping}")
                continue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant