anthropics/skills · error · FileNotFoundError

{word} not found (not an unpacked .docx?)

Error message

{word} not found (not an unpacked .docx?)

What it means

Raised by add_comment() (and its CLI wrapper in comment.py) when the unpacked directory does not contain a word/ subdirectory, which every real unpacked .docx must have. It signals the caller passed a directory that is not an unpacked OOXML package — e.g. a zip extracted from something other than a DOCX, or the parent of the unpacked tree.

Source

Thrown at skills/docx/scripts/comment.py:251


def add_comment(
    unpacked_dir: Path | str,
    text: str,
    comment_id: int | None = None,
    author: str = "Claude",
    initials: str = "C",
    parent_id: int | None = None,
    raw: bool = False,
) -> 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)

View on GitHub (pinned to f6656c1256)

Solutions

  1. Unpack the DOCX first (e.g. 'unzip file.docx -d file_unpacked') and pass that directory so that file_unpacked/word exists.
  2. Check you passed the unpacked directory, not the .docx file path and not the parent of the unpacked tree.
  3. Confirm the source file is actually a DOCX ('unzip -l file.docx | grep word/document.xml').
  4. If using a custom unpack helper, verify it preserved internal structure rather than flattening entries.

Example fix

# before
add_comment(unpacked_dir=Path("report.docx"), text="note")  # FileNotFoundError

# after
import zipfile, tempfile
with zipfile.ZipFile("report.docx") as zf, tempfile.TemporaryDirectory() as td:
    zf.extractall(td)
    add_comment(unpacked_dir=Path(td), text="note")
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def is_unpacked_docx(unpacked_dir: str | Path) -> bool:
    return (Path(unpacked_dir) / "word").is_dir() and (Path(unpacked_dir) / "word" / "document.xml").exists()

Try / catch

from pathlib import Path
try:
    add_comment(unpacked_dir=d, text="note")
except FileNotFoundError as e:
    if "not an unpacked .docx" in str(e):
        raise RuntimeError(f"unpack {d} first: expected {d}/word to exist") from e
    raise

Prevention

When it happens

Trigger: Calling add_comment(unpacked_dir=...) (or the comment.py CLI with --raw/--unpacked-style flow) where unpacked_dir lacks a 'word' child: passing the .docx file path itself instead of the unpacked directory, passing the zip's root when it contains only 'ppt/' or 'xl/', or passing a directory that was never unpacked.

Common situations: Forgetting to run the unpack step before commenting; operating on PPTX/XLSX files with the docx tooling; passing the directory that CONTAINS the unpacked tree (one level too high); a previous unpack step failed silently leaving an empty directory.

Related errors


AI-assisted analysis of anthropics/skills@f6656c1256 (2026-08-14). Data as JSON: /api/errors/70b071be06bb7d95. Report an issue: GitHub.