{"record":{"id":"7c808fc9db1248bc","repo":"anthropics/skills","slug":"pdf-conversion-failed-detail","errorCode":null,"errorMessage":"PDF conversion failed: {detail}","messagePattern":"PDF conversion failed: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/pptx/scripts/thumbnail.py","lineNumber":198,"sourceCode":"    img = Image.new(\"RGB\", size, color=\"#F0F0F0\")\n    draw = ImageDraw.Draw(img)\n    line_width = max(5, min(size) // 100)\n    draw.line([(0, 0), size], fill=\"#CCCCCC\", width=line_width)\n    draw.line([(size[0], 0), (0, size[1])], fill=\"#CCCCCC\", width=line_width)\n    return img\n\n\ndef convert_to_images(pptx_path: Path, temp_dir: Path) -> list[Path]:\n    pdf_path = temp_dir / f\"{pptx_path.stem}.pdf\"\n\n    result = run_soffice(\n        [\"--headless\", \"--convert-to\", \"pdf\", \"--outdir\", str(temp_dir), str(pptx_path)],\n        capture_output=True,\n        text=True,\n    )\n    if result.returncode != 0 or not pdf_path.exists():\n        detail = (result.stderr or result.stdout or \"\").strip()\n        raise RuntimeError(f\"PDF conversion failed: {detail}\" if detail else \"PDF conversion failed\")\n\n    result = subprocess.run(\n        [\n            \"pdftoppm\",\n            \"-jpeg\",\n            \"-r\",\n            str(CONVERSION_DPI),\n            str(pdf_path),\n            str(temp_dir / \"slide\"),\n        ],\n        capture_output=True,\n        text=True,\n    )\n    if result.returncode != 0:\n        raise RuntimeError(\"Image conversion failed\")\n\n    return sorted(temp_dir.glob(\"slide-*.jpg\"))\n","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/anthropics/skills/blob/f6656c1256d5a8adfa37db9110046ef20bac644c/skills/pptx/scripts/thumbnail.py#L180-L216","documentation":"Raised when converting a PPTX to PDF via LibreOffice (`soffice --headless --convert-to pdf`) either exits non-zero or produces no output PDF. The message appends LibreOffice's stderr/stdout as detail. It means the external soffice process itself failed or silently produced nothing.","triggerScenarios":"Calling convert_to_images(pptx_path, temp_dir) when: LibreOffice is not installed or `soffice` is not on PATH; the .pptx is corrupt/password-protected so LibreOffice aborts; a stale soffice profile lock prevents headless startup; the expected output file temp_dir/{stem}.pdf was not created even though returncode was 0.","commonSituations":"CI containers without libreoffice installed; first-ever headless run after a crashed LibreOffice leaves a locked user profile (~/.config/libreoffice/4/user/.lock); running while another soffice instance is starting; filenames with characters LibreOffice mangles so the produced PDF name differs from {stem}.pdf.","solutions":["Run `soffice --headless --convert-to pdf --outdir /tmp test.pptx` manually and read the stderr echoed in the message","Install LibreOffice (e.g. `apt-get install -y libreoffice` on Debian/Ubuntu) or add it to the CI image","Clear a stuck profile lock: delete ~/.config/libreoffice/4/user/.lock or run with `-env:UserInstallation=file:///tmp/lo_profile`","If the file is corrupt/unopenable, repair or regenerate the PPTX before thumbnailing"],"exampleFix":"// before\nresult = run_soffice([\"--headless\", \"--convert-to\", \"pdf\", \"--outdir\", str(temp_dir), str(pptx_path)], capture_output=True, text=True)\n// after: isolated profile avoids the single-instance/profile-lock failure mode\nresult = run_soffice([\n    \"--headless\",\n    \"-env:UserInstallation=file:///tmp/lo_thumb_profile\",\n    \"--convert-to\", \"pdf\",\n    \"--outdir\", str(temp_dir),\n    str(pptx_path),\n], capture_output=True, text=True)","handlingStrategy":"validation","validationCode":"import shutil\nfrom pathlib import Path\n\ndef can_convert_pptx(pptx_path: Path) -> tuple[bool, str]:\n    if shutil.which(\"soffice\") is None:\n        return False, \"LibreOffice (soffice) not on PATH\"\n    if not pptx_path.is_file() or pptx_path.stat().st_size == 0:\n        return False, f\"missing or empty file: {pptx_path}\"\n    return True, \"\"","typeGuard":null,"tryCatchPattern":"try:\n    images = convert_to_images(pptx, tmp)\nexcept RuntimeError as e:\n    log.error(\"thumbnail pipeline failed: %s\", e)  # message embeds soffice stderr\n    raise ThumbnailUnavailable(pptx) from e","preventionTips":["Bake libreoffice into the CI/dev image and smoke-test `soffice --version` at startup","Use a dedicated -env:UserInstallation profile per conversion to dodge profile locks","Fail fast on zero-byte or unopenable pptx inputs before invoking soffice"],"tags":["libreoffice","pdf","subprocess","conversion","pptx"],"backgroundTag":null,"analyzedSha":"f6656c1256d5a8adfa37db9110046ef20bac644c","analyzedAt":"2026-08-14T16:09:17.493Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}