Skip to content

[Bug] PipelineDumper 输出 ColorMatch 的 lower/upper 为空数组 [],但 parser 拒绝接受空数组(无法重新加载 dumper 自己的输出) #1315

@sunyink

Description

@sunyink

问题类型 / Issue Type

一般 Bug / General Bug

问题描述及复现步骤 / Problem Description & Reproduction Steps

1. 问题描述及复现步骤

预期行为

两条路径之一:

  • lower / upper 字段没在用户配置中出现时,parser 应走"用 default 值"分支(这条已实现)
  • dumper 输出的形态应能被 parser 接受(这条没实现,导致 round-trip 断)

实际行为

在 ColorMatch type 下用户没填 lower/upper 时,dumper 输出形态为:

{
    "recognition": {
        "type": "ColorMatch",
        "param": {
            "lower": [],          ← 空数组
            "upper": [],          ← 空数组
            "method": 4,
            "count": 1,
            "connected": false
        }
    }
}

Parser 看到 lower:[] 时报错:

[ERR] type error [key=lower] [input={"lower":[],...}]
[ERR] failed to parse_color_matcher_param

源码原因

PipelineParser.cppget_and_check_array_or_2darray 函数:

auto opt = input.find(key);
if (!opt) {
    output = default_value;
    return true;                  // 字段不存在 → OK
}
if (!opt->is_array() || opt->as_array().empty()) {
    LogError << "type error" ...;
    return false;                 // 字段存在但是空 → 报错
}

字段不存在走"用 default" → OK;字段存在但值是 [] → 报错。两条路径行为不一致。
而 dumper 写 lower: [],触发了第二条报错路径。

复现步骤

  1. 准备 task:{"_test_": {"recognition": "ColorMatch"}}(V1 简洁写法,不写 param)
  2. 加载成功(parser 走"字段不存在 → 用 default"分支)
  3. get_node_data("_test_") 拿 dump 输出,得到 {lower:[], upper:[], ...}
  4. 把 dump 输出写到文件,重新 post_pipeline 加载
  5. 加载失败

也可以直接测:写 {"_test_": {"recognition": "ColorMatch", "lower": []}} 当任何 task → 立即报错。

最小复现脚本

from maa.resource import Resource
import json, tempfile, pathlib

with tempfile.TemporaryDirectory() as tmp:
    p = pathlib.Path(tmp) / "test.json"
    p.write_text(json.dumps({
        "_test_": {"recognition": "ColorMatch"}
    }), encoding="utf-8")
    
    res = Resource()
    res.post_pipeline(str(tmp)).wait()
    assert res.loaded, "first load should succeed"
    
    dumped = res.get_node_data("_test_")
    print("Dump output (含 lower:[]):", json.dumps(dumped, indent=2))
    
    p.unlink()
    p2 = pathlib.Path(tmp) / "redumped.json"
    p2.write_text(json.dumps({"_test_": dumped}), encoding="utf-8")
    
    res2 = Resource()
    res2.post_pipeline(str(tmp)).wait()
    print("Second load:", "succeeded" if res2.loaded else "FAILED")

2. 关于复现的其他信息

  • MaaFramework 版本: 5.10.0b2
  • Python 包: maafw 5.10.0b2 (PyPI)
  • 环境: Windows 10, Python 3.11
  • 触发场景: 用户从 OCR/TM 等切换到 ColorMatch type 时,dumper 自动填的 lower:[] 让产物无法重新加载
  • 相关源码位置:
    • 报错位置: PipelineParser.cpp 第 132-136 行 get_and_check_array_or_2darray
    • dumper 输出位置: PipelineDumper.cpp ColorMatch param 处理
  • 建议修复方向(任选其一):
    • dumper 不输出值为 [] 的 lower/upper(让 parser 走"字段不存在用 default"分支)
    • 或者 parser 接受空数组作为"用 default"的等价表达

背景

我在做第三方工具 MaaOWM (MaaFramework Overlay Workspace Manager),依赖 PipelineParser/Dumper 的 round-trip 闭合性。集成时发现这个问题。

MaaFramework 版本 / Version

5.10.0b2 (PyPI)

日志文件 / Log Files

Null

Pipeline JSON

崩溃 Dump 文件 / Crash Dump (仅崩溃问题 / Crash only)

No response

Draw 调试图片 / Draw Debug Images (仅识别问题 / Recognition only)

No response

模板图片 / Template Images (仅识别问题 / Recognition only)

No response

其他信息 / Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething 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