anthropics/skills · error · ValueError
parent comment {parent_id} not found
Error message
parent comment {parent_id} not found What it means
Raised by add_comment() when a parent_id was supplied for a reply comment but no comment with that ID could be found in word/comments.xml (or comments.xml does not exist yet, so no parent can exist). It prevents writing a reply that references a nonexistent parent, which would produce a corrupt or orphaned comment thread.
Source
Thrown at skills/docx/scripts/comment.py:261
) -> tuple[int, str, str]:
unpacked_dir = Path(unpacked_dir)
if not raw:
text = xml_escape(text)
author = xml_escape(author, {'"': """})
initials = xml_escape(initials, {'"': """})
word = unpacked_dir / "word"
if not word.exists():
raise FileNotFoundError(f"{word} not found (not an unpacked .docx?)")
comments = word / "comments.xml"
if comment_id is None:
comment_id = _next_comment_id(comments)
parent_para = None
if parent_id is not None:
parent_para = _find_para_id(comments, parent_id) if comments.exists() else None
if not parent_para:
raise ValueError(f"parent comment {parent_id} not found")
para_id, durable_id = _generate_hex_id(), _generate_hex_id()
ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
if not comments.exists():
shutil.copy(TEMPLATE_DIR / "comments.xml", comments)
_ensure_comment_relationships(unpacked_dir)
_ensure_comment_content_types(unpacked_dir)
_append_xml(
comments,
"w:comments",
COMMENT_XML.format(
id=comment_id, author=author, date=ts, initials=initials,
para_id=para_id, text=text,
),
)
ext = word / "commentsExtended.xml"View on GitHub (pinned to f6656c1256)
Solutions
- List existing comments first (read word/comments.xml w:comment/@w:id) and pass a verified id as parent_id.
- If the document genuinely has no comments, drop parent_id and create a top-level comment instead.
- Re-extract IDs from the CURRENT document version rather than reusing IDs from a prior edit session.
- If comments.xml is missing unexpectedly, confirm you are operating on the same unpacked tree the earlier comments were added to.
Example fix
# before
add_comment(unpacked_dir=d, text="reply", parent_id=7) # ValueError if 7 absent
# after
from defusedxml import minidom
ids = {c.getAttribute("w:id") for c in minidom.parse(str(d/"word"/"comments.xml")).getElementsByTagName("w:", )} if False else {c.getAttribute("w:id") for c in minidom.parse(str(d/"word"/"comments.xml")).getElementsByTagName("w:comment")}
add_comment(unpacked_dir=d, text="reply", parent_id=7 if "7" in ids else None) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
from defusedxml import minidom
def comment_ids(unpacked_dir: Path) -> set[str]:
f = Path(unpacked_dir) / "word" / "comments.xml"
if not f.exists():
return set()
return {c.getAttribute("w:id") for c in minidom.parseString(f.read_bytes()).getElementsByTagName("w:comment")} Try / catch
try:
add_comment(unpacked_dir=d, text="reply", parent_id=pid)
except ValueError as e:
if "parent comment" in str(e):
add_comment(unpacked_dir=d, text=text) # degrade to top-level comment, or re-fetch IDs
else:
raise Prevention
- Fetch the live comment ID list from word/comments.xml in the same run before replying.
- Never reuse comment IDs across edits of the document.
- For brand-new threads, omit parent_id.
- Distinguish w:id (comment id) from w15:paraId/durableId — only w:id is accepted as parent_id.
When it happens
Trigger: Calling add_comment(..., parent_id=N) where N is not a comment id present in word/comments.xml — e.g. N came from a previous run against a different document, comments.xml was deleted/never created, or the ID was read from a tool that reports para ids rather than comment ids.
Common situations: Reply workflows where the caller cached comment IDs from an older version of the document; documents with no existing comments (comments.xml absent) where a reply was attempted; ID confusion between w:comment/@w:id, w15:paraId, and durableId.
Related errors
- {word} not found (not an unpacked .docx?)
- relationship target is not a POSIX part name: {target!r}
- relationship target resolves to nothing: {target!r}
- relationship target escapes the package: {target!r}
- symlink archive entry not allowed: {m.filename!r}
AI-assisted analysis of anthropics/skills@f6656c1256 (2026-08-14).
Data as JSON: /api/errors/5a4e7078b54efef4.
Report an issue: GitHub.