Skip to content

SplitPdfHook raises NotImplementedError while partitioning a DOC with an embedded encrypted PDF #364

Open

Description

@letsgo00-max

Describe the bug

When partitioning a legacy .doc Word document that contains an embedded PDF, the Python SDK's SplitPdfHook.before_request() can raise:

NotImplementedError: only Standard PDF encryption handler is available

This happens on the client, before the partition request reaches the Unstructured API. A normal .doc without the embedded PDF is successfully partitioned through the same setup. The embedded PDF opens in WPS without a password prompt, but appears to use a PDF encryption handler unsupported by pypdf.

The failure is surprising because the input being partitioned is a DOC file, not a PDF that the caller requested to split.

Environment

  • Integration: self-hosted Dify 1.13.3, workflow Document Extractor node, calling a self-hosted Unstructured API.
  • Failing process: Dify worker container.
  • Python: 3.11 (from traceback).
  • unstructured-client: Dify 1.13.3's api/uv.lock pins 0.42.4 (the traceback's split_pdf_hook.py:293 matches this tag; actual installed package versions have not been separately confirmed).
  • pypdf: Dify 1.13.3's lockfile pins 6.9.1 (actual installed version not separately confirmed).
  • No sample document attached because the source document is from an internal environment.

Steps to reproduce

  1. Prepare a legacy Word .doc with an embedded PDF using an encryption/security handler that pypdf does not support. In this report, the embedded PDF opens in WPS without requiring a password.
  2. Upload the DOC to a Dify workflow's Document Extractor node configured to use Unstructured.
  3. The worker calls unstructured.partition.api.partition_via_api(...) with the DOC content.
  4. Observe the exception from the SDK request hook. A plain DOC without this embedded PDF works.

A standalone SDK reproduction to try with the same document:

from unstructured.partition.api import partition_via_api

elements = partition_via_api(
    filename="problem.doc",
    api_url="http://<unstructured-host>:8000/general/v0/general",
    api_key="",
)

Actual behavior

Relevant traceback (local path prefix omitted):

unstructured_client/_hooks/sdkhooks.py:48, in before_request
    out = hook.before_request(hook_ctx, request)
unstructured_client/_hooks/custom/split_pdf_hook.py:293, in before_request
    pdf = pdf_utils.read_pdf(pdf_file)
unstructured_client/_hooks/custom/pdf_utils.py:42, in read_pdf
    return PdfReader(pdf_file, strict=False)
pypdf/_reader.py:155, in __init__
    self._handle_encryption(password)
pypdf/_reader.py:182, in _handle_encryption
    self._encryption = Encryption.read(encrypt_entry, id1_entry)
pypdf/_encryption.py:1093, in read
    raise NotImplementedError(
NotImplementedError: only Standard PDF encryption handler is available

In unstructured-client v0.42.4, pdf_utils.read_pdf() catches (PdfReadError, UnicodeDecodeError), but does not catch this NotImplementedError:

https://github.com/Unstructured-IO/unstructured-python-client/blob/v0.42.4/src/unstructured_client/_hooks/custom/pdf_utils.py

The calling hook is here (lines 279–293):

https://github.com/Unstructured-IO/unstructured-python-client/blob/v0.42.4/src/unstructured_client/_hooks/custom/split_pdf_hook.py#L279-L293

Expected behavior

For non-PDF inputs, PDF splitting/preflight should not abort partitioning because the payload contains an embedded/recognizable PDF structure. Ideally the SDK detects whether the top-level input is a PDF before attempting PdfReader, and lets non-PDF documents proceed to the server unchanged. For actual encrypted PDFs with unsupported handlers, a clear validation error may still be appropriate.

Possible workaround / suggested fix

The source shows the hook returns early if split_pdf_page is absent or "false", before invoking pdf_utils.read_pdf(). Passing split_pdf_page=False to partition_via_api() should therefore avoid this specific client-side traceback; we have not yet verified end-to-end parsing of the problematic document after applying it.

Could the client skip PDF preflight for non-PDF top-level files, and/or handle the NotImplementedError from pypdf more gracefully without silently accepting unsupported encrypted PDFs?

Additional context

Dify 1.13.3 calls the SDK from:

https://github.com/langgenius/dify/blob/1.13.3/api/dify_graph/nodes/document_extractor/node.py#L365-L389

Dify 1.18.0 still pins unstructured-client==0.42.4 in its lockfile, so upgrading Dify alone has not been established as a fix.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions