anthropics/skills · error · ValueError

relationship target is not a POSIX part name: {target!r}

Error message

relationship target is not a POSIX part name: {target!r}

What it means

opc_target() normalizes OOXML relationship targets into POSIX part names. It rejects any target containing a backslash, because OPC part names use forward slashes only; a backslash means the producer wrote a Windows-style or malformed path, and silently normalizing it could point at the wrong part. Thrown by both the docx and pptx copies of office/helpers/__init__.py.

Source

Thrown at skills/docx/scripts/office/helpers/__init__.py:35

}

_SCHEME_RE = re.compile(r"^[A-Za-z][A-Za-z0-9+.\-]*:")

SLIDE_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"


def opc_target(target: str, source_part: str, target_mode: str = "") -> str | None:
    if not target:
        return None
    if target_mode.lower() == "external":
        return None
    if _SCHEME_RE.match(target):
        return None

    target = urllib.parse.unquote(target)

    if "\\" in target:
        raise ValueError(f"relationship target is not a POSIX part name: {target!r}")

    if target.startswith("/"):
        joined = target.lstrip("/")
    else:
        joined = posixpath.join(posixpath.dirname(source_part), target)

    parts: list[str] = []
    for segment in posixpath.normpath(joined).split("/"):
        if segment in ("", "."):
            continue
        if segment == "..":
            if not parts:
                raise ValueError(f"relationship target escapes the package: {target!r}")
            parts.pop()
        else:
            parts.append(segment)

    if not parts:

View on GitHub (pinned to f6656c1256)

Solutions

  1. Inspect the offending .rels file (message includes the target) and rewrite backslashes to forward slashes: Target="media/image1.png".
  2. Re-save the file with PowerPoint/Word or LibreOffice, which rewrite conformant relationships.
  3. If you must process such files programmatically, pre-normalize targets with target.replace('\\', '/') before calling opc_target (only as a repair step, not silently).
  4. Report the non-conforming file to whatever generator produced it.

Example fix

<!-- before: ppt/slides/_rels/slide1.xml.rels -->
<Relationship Id="rId2" Type=".../image" Target="..\\media\\image1.png"/>

<!-- after -->
<Relationship Id="rId2" Type=".../image" Target="../media/image1.png"/>
Defensive patterns

Strategy: validation

Validate before calling

import zipfile, re

def rels_targets_ok(path: str) -> tuple[bool, str | None]:
    with zipfile.ZipFile(path) as zf:
        for name in zf.namelist():
            if not name.endswith(".rels"):
                continue
            for m in re.finditer(rb'Target="([^"]*)"', zf.read(name)):
                t = m.group(1).decode()
                if "\\" in t:
                    return False, f"{name}: backslash target {t!r}"
    return True, None

Try / catch

try:
    opc_target(target, source_part, target_mode)
except ValueError as e:
    if "not a POSIX part name" in str(e):
        opc_target(target.replace("\\", "/"), source_part, target_mode)  # explicit repair, log it
    else:
        raise

Prevention

When it happens

Trigger: Any relationship in a .rels file whose Target attribute contains '\\' — e.g. Target="..\\theme\\theme1.xml" or Target="media\\image1.png", produced by non-conforming generators or hand-edited packages, when the package is unpacked and scanned (thumbnail.py get_slide_info, clean.py referenced-file walk, comment.py flows).

Common situations: PPTX/DOCX files generated by third-party tools (older converters, some report generators) that write Windows paths into .rels; packages that were unzipped/rezipped on Windows with path mangling; malicious or fuzzed inputs.

Related errors


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