已关闭
[Bug]: `rebuild_dict` loses nested lists under dicts #1001
Nguyễn Thanh Toàn创建于  6月8日关闭于  6月25日
Nguyễn Thanh Toàn
Nguyễn Thanh Toàn
6月8日 创建

Checklist

🐞 Detailed Description of the Problem

Severity: HIGH
File: openjiuwen/core/common/utils/dict_utils.py ~line 163
Discovered by: Property-based testing (Hypothesis)


Summary

rebuild_dict silently drops nested lists when a path contains two consecutive list indices. The result is a structurally wrong output with no error raised.


Reproducer

from openjiuwen.core.common.utils.dict_utils import extract_leaf_nodes, rebuild_dict

data = {'a': [[1]]}
leaves = extract_leaf_nodes(data)
# leaves: [(['a', '[0]', '[0]'], 1)]

result = rebuild_dict(leaves)
print(result)  # {'a': [{}]}  ← wrong, should be {'a': [[1]]}

Expected vs Actual

Value
Input {'a': [[1]]}
Expected {'a': [[1]]}
Actual {'a': [{}]}

Root Cause

The primary bug is in the intermediate traversal loop (~line 163–172). When a path element is a list index ('[0]') and current is not already a list, the code saves the old reference in current_parent_ref and rebinds current to a new list — but never writes the new list back into the parent. current_parent_ref is a dead variable; it is assigned and never read again:

# traversal loop — intermediate step (~line 163–176)
if not isinstance(current, list):
    current_parent_ref = current   # ← assigned but never used again
    current = []                   # ← local rebind only; parent still holds {}
# Expand list to required length
while len(current) <= index:
    current.append({})
current = current[index]           # ← steps into {} inside an orphaned list

Because the new list is never linked into the tree, subsequent traversal proceeds through {} placeholders unreachable from result. The same flaw is repeated in the final-value assignment block (~line 189–195):

last_key = path[-1]
if isinstance(last_key, str) and last_key.startswith('[') and last_key.endswith(']'):
    index = int(last_key[1:-1])
    if not isinstance(current, list):
        current = []          # ← same dead rebind
    while len(current) <= index:
        current.append(None)
    current[index] = value    # ← written to orphaned list, discarded

Fixing only the final block would leave the traversal bug intact. Both sites need the same fix.


Impact

Affects any structure with a list-of-lists or list-of-dicts-containing-lists pattern:

{'results': [[1, 2], [3, 4]]}
{'items': [{'tags': ['a', 'b']}]}

The round-trip extract_leaf_nodesrebuild_dict is not reliable for these shapes.

In current example usage, stream_inputs_schema values are all flat dicts with string refs, so the bug is not triggered by any existing workflow. However, list-valued schemas are a supported shape (the framework handles them in vertex.py:453–456), and any user who passes a nested-list schema to stream_inputs_schema will receive silently corrupted inputs at stream time with no error raised.


Suggested Fix

Track parent and parent_key/parent_index through the loop. At both the intermediate and final list-index sites, write the new list back into the parent before using it:

if not isinstance(current, list):
    new_list = []
    if isinstance(parent, list):
        parent[parent_index] = new_list
    else:
        parent[parent_key] = new_list
    current = new_list

The existing current_parent_ref variable is a dead stub of exactly this intent — it was clearly meant to enable this write-back but was never wired up.

Detailed Environment Information Description

As above.

Additional Information

Version Information

Thanks for your contribution 🎉!

likedislike
openJiuwen-bot成员
6月8日 评论:

注意

此 Issue 需要负责人。 如果没有指派时, iamcandiceguo 是默认的负责人

likedislike
OopenJiuwen-bot成员
6月8日 将 iamcandiceguo 设为负责人
OopenJiuwen-bot成员
6月8日 添加了label:sig/sig-agent-core
openJiuwen-bot成员
6月8日 评论:

欢迎来到 openJiuwen 社区

Hey @thanhtoantnt , 感谢你对社区的贡献.

机器人使用手册

有关指令的使用,可以点击 此处 查看详情。开发人员可以在每个PR或Issue下方评论特定指令来触发机器人任务。

联系指引

有疑问可以联系 SIG: sig-agent-core ,
维护者是: @seanzhang_cn, @xinyu-jiuwen ,
审核者是: @SnapeK, @alan_cheng, @deyang, @iamcandiceguo .

likedislike
Nguyễn Thanh ToànNguyễn Thanh Toàn
6月8日 关联了pull request:fix: rebuild_dict loses nested lists under dicts
Gguoqian成员
6月12日 将 thanhtoantnt 设为负责人
Gguoqian成员
6月12日 移除了负责人 iamcandiceguo
Gguoqian成员
6月12日 关联了里程碑:V0.1.15
Gguoqian成员
6月15日 移除了里程碑
Gguoqian成员
6月25日 issue状态由 TODO 改变为 CLOSED
Gguoqian成员
6月25日 关闭了 issue