anthropics/skills · error · ValueError
relationship target escapes the package: {target!r}
Error message
relationship target escapes the package: {target!r} What it means
opc_target() resolves a relative relationship target against the source part and rejects targets whose normalized path climbs above the package root ('..' more times than there are path segments). OPC part names are package-absolute; escaping the root means the target is malformed and any resolution would be arbitrary. Present in both docx and pptx copies of office/helpers/__init__.py.
Source
Thrown at skills/docx/scripts/office/helpers/__init__.py:48
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:
raise ValueError(f"relationship target resolves to nothing: {target!r}")
return "/".join(parts)
def rels_source_part(rels_file: Path, unpacked_dir: Path) -> str:
owner_dir = rels_file.parent.parent.relative_to(unpacked_dir)
return posixpath.join(owner_dir.as_posix(), rels_file.name[: -len(".rels")]).lstrip("./")
def part_text(data: bytes) -> str:
return data.decode("utf-8", "surrogateescape")
View on GitHub (pinned to f6656c1256)
Solutions
- Open the .rels file named in your processing log and fix the Target so it stays inside the package (e.g. '../media/image1.png' from ppt/slides/_rels/, not '../../../../media/image1.png').
- Remember relative targets resolve against the RELATIONSHIP FILE'S owner part directory, not the package root — use a leading '/' for package-absolute targets.
- If the input is untrusted, treat this error as a security signal and quarantine the file rather than repairing it.
- Regenerate the package with a conformant tool (PowerPoint, python-pptx, openpyxl).
Example fix
<!-- before --> <Relationship Id="rId1" Type=".../slide" Target="../../../../slides/slide1.xml"/> <!-- after: package-absolute target --> <Relationship Id="rId1" Type=".../slide" Target="/ppt/slides/slide1.xml"/>
Defensive patterns
Strategy: validation
Validate before calling
import posixpath
def target_stays_in_package(target: str, source_part: str) -> bool:
if not target or target.startswith("/"):
return True # absolute targets cannot escape via '..'
joined = posixpath.normpath(posixpath.join(posixpath.dirname(source_part), target))
return not joined.startswith("..") and "/.." not in joined Try / catch
try:
opc_target(target, source_part, target_mode)
except ValueError as e:
if "escapes the package" in str(e):
log.security("traversal target rejected: %r from %s", target, source_part)
skip_relationship() # never auto-repair untrusted traversal targets
else:
raise Prevention
- Prefer package-absolute targets (leading '/') when authoring .rels files.
- Treat 'escapes the package' on untrusted input as a security event, not a bug to patch.
- Run packages through an OOXML validator before processing.
- Count '..' segments against the source part depth when hand-writing relative targets.
When it happens
Trigger: A relationship like Target="../../../../etc/passwd" or "../../outside.xml" attached to a part near the root (e.g. source_part='_rels/.rels' with heavy '../' traversal); also '..' as the very first segment of an absolute-style target after normpath.
Common situations: Zip-slip-style traversal attempts in malicious or fuzzed OOXML files; hand-built .rels files where the author counted directory levels wrong; converters that emit '../../' prefixes relative to the wrong base part.
Related errors
- 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}
- unsafe archive entry: {m.filename!r}
AI-assisted analysis of anthropics/skills@f6656c1256 (2026-08-14).
Data as JSON: /api/errors/b8767cd981a518a6.
Report an issue: GitHub.