anthropics/skills · error · ValueError
relationship target resolves to nothing: {target!r}
Error message
relationship target resolves to nothing: {target!r} What it means
opc_target() raises this when a non-empty relationship target normalizes to an empty part name — every segment was '.', empty, or consumed by '..' pops (e.g. Target='.', Target='./', or 'a/..'). OPC requires each relationship to name a real part; an empty resolution means the .rels entry is corrupt. Exists in both the docx and pptx copies of office/helpers/__init__.py.
Source
Thrown at skills/docx/scripts/office/helpers/__init__.py:54
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")
XML_SPACE = " \t\r\n"
def rendered_text(text: str, preserve: bool) -> str:
return text if preserve else text.strip(XML_SPACE)
View on GitHub (pinned to f6656c1256)
Solutions
- Find the Relationship whose target is '.' or './' (the message shows it) and point it at the intended part, or remove the dead relationship entry entirely.
- If the relationship is vestigial (e.g. an external link wrongly marked internal), delete the <Relationship> element from the .rels file.
- Re-save through PowerPoint/LibreOffice to let a conformant writer rebuild the .rels files.
- Validate the package with an OOXML validator before feeding it to these scripts.
Example fix
<!-- before --> <Relationship Id="rId5" Type=".../customXml" Target="."/> <!-- after: remove or point at a real part --> <!-- <Relationship ... /> deleted -->
Defensive patterns
Strategy: validation
Validate before calling
import posixpath
def target_resolves_to_part(target: str, source_part: str) -> bool:
if not target:
return False
joined = posixpath.normpath(posixpath.join(posixpath.dirname(source_part), target)) if not target.startswith("/") else posixpath.normpath(target.lstrip("/"))
return joined not in ("", ".") Try / catch
try:
opc_target(target, source_part, target_mode)
except ValueError as e:
if "resolves to nothing" in str(e):
drop_relationship() # dead entry; remove from .rels rather than guess
else:
raise Prevention
- Never write placeholder targets like '.' or './' into .rels files.
- Remove relationships you intend to delete instead of blanking their Target.
- Validate generated packages with an OOXML validator before shipping.
When it happens
Trigger: A Relationship element with Target=".", Target="./", or a target that self-cancels like "word/document.xml/.."; occurs while scanning any .rels file during unpack-based operations (thumbnails, cleaning, comment insertion).
Common situations: Hand-edited or machine-generated .rels with placeholder targets; tools that write Target="" variants for relationships they mean to delete; round-tripped files from buggy serializers.
Related errors
- relationship target is not a POSIX part name: {target!r}
- relationship target escapes the package: {target!r}
- relationship target is not a POSIX part name: {target!r}
- relationship target resolves to nothing: {target!r}
- {word} not found (not an unpacked .docx?)
AI-assisted analysis of anthropics/skills@f6656c1256 (2026-08-14).
Data as JSON: /api/errors/034f2464eb60e840.
Report an issue: GitHub.