{"record":{"id":"22f9ed538896fbf3","repo":"anthropics/skills","slug":"relationship-target-resolves-to-nothing-target-r-22f9ed","errorCode":null,"errorMessage":"relationship target resolves to nothing: {target!r}","messagePattern":"relationship target resolves to nothing: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/pptx/scripts/office/helpers/__init__.py","lineNumber":54,"sourceCode":"\n    if target.startswith(\"/\"):\n        joined = target.lstrip(\"/\")\n    else:\n        joined = posixpath.join(posixpath.dirname(source_part), target)\n\n    parts: list[str] = []\n    for segment in posixpath.normpath(joined).split(\"/\"):\n        if segment in (\"\", \".\"):\n            continue\n        if segment == \"..\":\n            if not parts:\n                raise ValueError(f\"relationship target escapes the package: {target!r}\")\n            parts.pop()\n        else:\n            parts.append(segment)\n\n    if not parts:\n        raise ValueError(f\"relationship target resolves to nothing: {target!r}\")\n    return \"/\".join(parts)\n\n\ndef rels_source_part(rels_file: Path, unpacked_dir: Path) -> str:\n    owner_dir = rels_file.parent.parent.relative_to(unpacked_dir)\n    return posixpath.join(owner_dir.as_posix(), rels_file.name[: -len(\".rels\")]).lstrip(\"./\")\n\n\ndef part_text(data: bytes) -> str:\n    return data.decode(\"utf-8\", \"surrogateescape\")\n\n\nXML_SPACE = \" \\t\\r\\n\"\n\n\ndef rendered_text(text: str, preserve: bool) -> str:\n    return text if preserve else text.strip(XML_SPACE)\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/anthropics/skills/blob/f6656c1256d5a8adfa37db9110046ef20bac644c/skills/pptx/scripts/office/helpers/__init__.py#L36-L72","documentation":"pptx copy of the empty-resolution guard (same as error 5): opc_target() raises when a non-empty relationship target normalizes to no part name at all (all segments '.', empty, or cancelled by '..' — e.g. Target='.' or 'slides/..'). Such an entry is corrupt; the library refuses to guess.","triggerScenarios":"A Relationship in a pptx .rels file with Target=\".\" or a self-cancelling path; encountered while thumbnail.py or clean.py walks relationships.","commonSituations":"Placeholder targets written by buggy serializers; relationships meant to be removed but left with a dummy target; hand-edited rels files.","solutions":["Delete the dead <Relationship> element or point it at the intended real part.","Re-save the deck with PowerPoint/LibreOffice to rebuild .rels files.","Validate the package (OOXML validator) before running cleaning/thumbnail pipelines.","If generating decks yourself with python-pptx or similar, upgrade — early versions had rels-writing bugs."],"exampleFix":"<!-- before -->\n<Relationship Id=\"rId3\" Type=\".../notesSlide\" Target=\".\"/>\n\n<!-- after: remove the element, or -->\n<Relationship Id=\"rId3\" Type=\".../notesSlide\" Target=\"../notesSlides/notesSlide1.xml\"/>","handlingStrategy":"validation","validationCode":"import posixpath\n\ndef target_resolves_to_part(target: str, source_part: str) -> bool:\n    if not target:\n        return False\n    joined = posixpath.normpath(posixpath.join(posixpath.dirname(source_part), target)) if not target.startswith(\"/\") else posixpath.normpath(target.lstrip(\"/\"))\n    return joined not in (\"\", \".\")","typeGuard":null,"tryCatchPattern":"try:\n    opc_target(target, source_part, target_mode)\nexcept ValueError as e:\n    if \"resolves to nothing\" in str(e):\n        drop_relationship()  # dead entry\n    else:\n        raise","preventionTips":["Never emit '.' or './' targets in .rels generation.","Delete unused <Relationship> elements instead of stubbing their Target.","Validate generated decks with an OOXML validator."],"tags":["pptx","ooxml","opc","relationships","validation"],"backgroundTag":null,"analyzedSha":"f6656c1256d5a8adfa37db9110046ef20bac644c","analyzedAt":"2026-08-14T16:09:17.493Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}