Non-empty list/dict `parentUuid` raises uncaught `TypeError` in session chain builders, killing the whole read

未关闭 适合新手
#1,507 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 2 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
72/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python
领域
backend

调研方向

从 src/claude_agent_sdk/_internal/sessions.py 中的 _build_conversation_chain(约第 960-964 行)开始,这里 parentUuid 被添加到一个集合中,然后检查第 1507-1508 行附近的 _build_subagent_chain。使用临时的 CLAUDE_CONFIG_DIR 运行 issue 中的复现步骤,以观察 TypeError。当包含非字符串 parentUuid 的转录返回其余消息,并且一个对照测试覆盖列表或字典值时,即完成。

由索引模型根据 Issue 内容生成。

描述

bug good first issue

Summary

The session chain builders assume parentUuid is a hashable string, but neither transcript parser validates parentUuid. A transcript entry with a non-empty list/dict parentUuid passes parsing, then raises an uncaught TypeError: unhashable type from get_session_messages (and the store-backed variants), killing the entire read instead of skipping or tolerating the malformed entry.

This is a correctness/error-handling bug, not a security vulnerability: triggering it requires a transcript file the caller already controls.

Version

  • Repo: anthropics/claude-agent-sdk-python
  • Package: claude-agent-sdk 0.2.181
  • Commit: 22b8eb9c19adfa78759b79e22bd664a57843bb06 (main, 2026-11-12)

Location

src/claude_agent_sdk/_internal/sessions.py:960-964 (_build_conversation_chain):

parent = entry.get("parentUuid")
if parent:
    parent_uuids.add(parent)

set.add on a list/dict raises TypeError: unhashable type. The same unvalidated-parentUuid pattern appears at :1507-1508 in _build_subagent_chain (by_uuid.get(parent)). Neither _parse_transcript_entries (:897-926) nor _filter_transcript_entries (:1814-1829) checks parentUuid — they validate only type and that uuid is a str. get_session_messages has no try/except around the chain build (:1330-1338).

Precise trigger: the parentUuid must be a non-empty list/dict. Falsy []/{} are skipped by if parent: and do not raise (verified as a control case).

Minimal repro

Against a temporary CLAUDE_CONFIG_DIR (never the real ~/.claude), with a transcript whose second entry has parentUuid: ["x"]:

import json, os, tempfile
from pathlib import Path
from claude_agent_sdk._internal import sessions

session_id = "550e8400-e29b-41d4-a716-446655440001"
entries = [
    {"uuid": "u1", "parentUuid": None, "type": "user",
     "message": {"role": "user", "content": "first"}},
    {"uuid": "u2", "parentUuid": ["x"], "type": "user",
     "message": {"role": "user", "content": "second"}},
]

with tempfile.TemporaryDirectory() as tmp:
    project_dir = Path(tmp) / "projects" / "tmp-proj"
    project_dir.mkdir(parents=True)
    (project_dir / f"{session_id}.jsonl").write_text(
        "".join(json.dumps(e) + "\n" for e in entries), encoding="utf-8"
    )
    os.environ["CLAUDE_CONFIG_DIR"] = tmp
    sessions.get_session_messages(session_id)

Observed: TypeError: unhashable type: 'list' propagates out of get_session_messages — the whole read fails, including the well-formed entries.

Expected: the malformed entry is skipped or its non-string parentUuid is treated as absent, and the read returns the remaining messages.

The store-backed variant (_filter_transcript_entries) and the subagent variant (_build_subagent_chain) share the unvalidated-parentUuid pattern by code reading; only the filesystem get_session_messages path was executed. A dict parentUuid (e.g. {"x": 1}) was not separately run — same unhashable mechanism as the list case.

Impact

One malformed entry in a session transcript makes the entire session unreadable via get_session_messages, instead of degrading gracefully. Any consumer reading sessions (resume flows, history views, tooling) hits an unhandled crash on the whole read. Local correctness impact only.

Suggested fix

Validate parentUuid in _parse_transcript_entries and _filter_transcript_entries (treat a non-string parentUuid as absent, or skip the entry), and/or guard the chain builders to ignore unhashable/non-string parent values.

Environment

  • Python 3.12.3, Linux
  • Verified end-to-end through the public get_session_messages() against a temp config dir at the pinned commit above. Baseline: a string-parentUuid chain reads 2 messages; control: falsy parentUuid: [] raises nothing.
主要语言
Python
星标
8.5k
派生
1.4k
平均合并
3 天 10 小时
30 天内合并 PR
13

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

anthropics/claude-agent-sdk-python 的其他 Issue

查看 anthropics/claude-agent-sdk-python 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。