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

Đang mở Phù hợp với người mới
#1,507 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 2 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
72/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python
Lĩnh vực
backend

Hướng nghiên cứu

Bắt đầu từ _build_conversation_chain trong src/claude_agent_sdk/_internal/sessions.py (khoảng dòng 960-964), nơi parentUuid được thêm vào một tập hợp, sau đó kiểm tra _build_subagent_chain gần dòng 1507-1508. Chạy bước tái hiện trong issue với một CLAUDE_CONFIG_DIR tạm thời để thấy TypeError. Hoàn thành khi một transcript có parentUuid không phải chuỗi trả về các tin nhắn còn lại, và một test đối chứng bao phủ giá trị kiểu list hoặc dict.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.
Ngôn ngữ chính
Python
Star
8.5k
Fork
1.4k
Merge trung bình
3 ngày 10 giờ
Pull request đã merge (30 ngày)
13

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của anthropics/claude-agent-sdk-python

Tất cả issue của anthropics/claude-agent-sdk-python

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.