{"record":{"id":"09b4257b1ea225e3","repo":"anthropics/skills","slug":"image-conversion-failed","errorCode":null,"errorMessage":"Image conversion failed","messagePattern":"Image conversion failed","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/pptx/scripts/thumbnail.py","lineNumber":213,"sourceCode":"    )\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\n\ndef create_grids(\n    slides: list[tuple[Path, str]],\n    cols: int,\n    width: int,\n    output_path: Path,\n) -> list[str]:\n    max_per_grid = cols * (cols + 1)\n    grid_files = []\n\n    for chunk_idx, start_idx in enumerate(range(0, len(slides), max_per_grid)):\n        end_idx = min(start_idx + max_per_grid, len(slides))\n        chunk_slides = slides[start_idx:end_idx]\n\n        grid = create_grid(chunk_slides, cols, width)","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/anthropics/skills/blob/f6656c1256d5a8adfa37db9110046ef20bac644c/skills/pptx/scripts/thumbnail.py#L195-L231","documentation":"Raised when `pdftoppm -jpeg -r DPI` (from poppler-utils) exits non-zero while rasterizing the PDF that LibreOffice just produced. It is the second stage of the pptx->pdf->jpg pipeline in thumbnail.py; the PDF exists but poppler could not turn it into slide-*.jpg images.","triggerScenarios":"Calling convert_to_images() on a machine where poppler-utils (pdftoppm) is missing (returncode 127); the generated PDF is malformed or zero pages; CONVERSION_DPI string is invalid; temp disk is full so writing slide-*.jpg fails.","commonSituations":"Alpine/slim Docker images that have LibreOffice but not the poppler package; a PPTX that LibreOffice converts into a damaged PDF; running as a user without write permission in temp_dir; very old poppler versions failing on newer PDF features.","solutions":["Install poppler-utils: `apt-get install -y poppler-utils` (or `apk add poppler-utils`)","Run `pdftoppm -jpeg -r 150 out.pdf /tmp/slide` by hand on the intermediate PDF to see the real exit status","Open the intermediate PDF (e.g. with pdfinfo) to confirm it is valid and has pages; if not, fix the stage-1 conversion (error 20)","Check temp_dir permissions and free disk space"],"exampleFix":"// before\nif result.returncode != 0:\n    raise RuntimeError(\"Image conversion failed\")\n// after: surface poppler's own diagnostics\ndetail = (result.stderr or result.stdout or \"\").strip()\nraise RuntimeError(f\"Image conversion failed: {detail}\" if detail else \"Image conversion failed\")","handlingStrategy":"validation","validationCode":"import shutil\n\ndef can_rasterize_pdf() -> bool:\n    return shutil.which(\"pdftoppm\") is not None","typeGuard":null,"tryCatchPattern":"try:\n    jpgs = convert_to_images(pptx, tmp)\nexcept RuntimeError as e:\n    if \"Image conversion\" in str(e):\n        log.error(\"poppler stage failed; install poppler-utils\")\n    raise","preventionTips":["Install poppler-utils alongside libreoffice in every environment that thumbnails","Check the intermediate PDF with pdfinfo before rasterizing when debugging","Treat missing binaries as a setup defect: verify both binaries at deploy time"],"tags":["poppler","pdftoppm","subprocess","pdf","thumbnail"],"backgroundTag":null,"analyzedSha":"f6656c1256d5a8adfa37db9110046ef20bac644c","analyzedAt":"2026-08-14T16:09:17.493Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}