{"record":{"id":"8976c08933a3d8b7","repo":"docling-project/docling","slug":"resource-bundle-does-not-contain-a-top-level-json","errorCode":null,"errorMessage":"Resource bundle does not contain a top-level JSON document.","messagePattern":"Resource bundle does not contain a top-level JSON document\\.","errorType":"exception","errorClass":"ArtifactDownloadError","httpStatus":null,"severity":"error","filePath":"docling/service_client/client.py","lineNumber":1808,"sourceCode":"    def _safe_extract_zip(bundle_zip: zipfile.ZipFile, base_dir: Path) -> None:\n        # Guard against zip-slip even though bundles originate from our service.\n        base_resolved = base_dir.resolve()\n        for member in bundle_zip.namelist():\n            target = (base_dir / member).resolve()\n            if target != base_resolved and base_resolved not in target.parents:\n                raise ArtifactDownloadError(\n                    f\"Resource bundle contains an unsafe path: {member!r}\"\n                )\n        bundle_zip.extractall(base_dir)\n\n    @staticmethod\n    def _find_bundle_json(base_dir: Path) -> Path:\n        # The server writes the document files at the bundle root and the\n        # referenced images under artifacts/, so the document JSON is the\n        # top-level *.json file.\n        candidates = sorted(base_dir.glob(\"*.json\"))\n        if not candidates:\n            raise ArtifactDownloadError(\n                \"Resource bundle does not contain a top-level JSON document.\"\n            )\n        return candidates[0]\n\n    def _embed_referenced_images(\n        self, document: DoclingDocument, base_dir: Path\n    ) -> None:\n        \"\"\"Inline images referenced as relative files under ``base_dir``.\n\n        This mirrors docling-core's ``DoclingDocument._with_embedded_pictures()``\n        but is reimplemented here because that helper only embeds picture images\n        and resolves relative ``Path`` URIs against the process working directory.\n        Bundle artifacts are extracted into a temporary directory, so both\n        picture and page image references must be resolved against ``base_dir``\n        explicitly before being inlined.\n        \"\"\"\n\n        base_resolved = base_dir.resolve()","sourceCodeStart":1790,"sourceCodeEnd":1826,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/service_client/client.py#L1790-L1826","documentation":"Raised as ArtifactDownloadError when, after extracting a resource bundle, no top-level *.json file can be found. The client expects the server to write the DoclingDocument JSON at the bundle root (with images under artifacts/); an empty or malformed bundle fails this check. Normally surfaced as a FAILURE ConversionResult, not thrown to callers.","triggerScenarios":"convert()/convert_all() with referenced-image bundle download where the ZIP contains only artifacts/ images, nested JSON files, or no JSON at all; sorted(glob('*.json')) at the extraction root returns nothing.","commonSituations":"Version mismatch between client and server bundle layout; server bug writing the document under a subdirectory; truncated/corrupted ZIP downloaded from an expiring presigned URL.","solutions":["Check ConversionResult.errors for this document; retry the conversion once in case of a truncated artifact download","Confirm client and docling-serve versions match (bundle layout is a shared contract)","Inspect the bundle manually by fetching the presigned URL with curl to see whether a root-level JSON exists"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"def is_artifact_download_error(exc: BaseException) -> bool:\n    return isinstance(exc, ArtifactDownloadError)","tryCatchPattern":"if res.status == ConversionStatus.FAILURE:\n    msgs = [e.error_message for e in res.errors]\n    if any('top-level JSON' in m for m in msgs):\n        retry_conversion(source)","preventionTips":["Pin client and server versions together — bundle layout is a shared contract","Retry once on malformed bundles to rule out truncated downloads"],"tags":["artifact-download","bundle-format","version-mismatch"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}