docling-project/docling

VLM pipeline MD/HTML conversion

Open

#2476 opened on Oct 16, 2025

View on GitHub
 (2 comments) (0 reactions) (0 assignees)Python (59,751 stars) (4,140 forks)batch import
buggood first issue

Description

Bug

Even though the fix (#2458) is applied, I still get the error ValueError: Can not append a child with children

Steps to reproduce

def create_converter():
    def openai_compatible_vlm_options(
            model: str,
            prompt: str,
            response_format: ResponseFormat,
            scheme_and_host,
            api_key: str = "",
    ):
        headers = {}
        if api_key:
            headers["Authorization"] = f"Bearer {api_key}"

        options = ApiVlmOptions(
            url=AnyUrl(f"{scheme_and_host}/v1/chat/completions"),
            params=dict(
                model=model,
            ),
            headers=headers,
            prompt=prompt,
            timeout=600,
            scale=2.0,
            temperature=1,
            response_format=response_format,
        )
        return options

    env = getenv()

    pdf_pipeline_options = VlmPipelineOptions(
        enable_remote_services=True,  # required when calling remote VLM endpoints
        vlm_options=openai_compatible_vlm_options(
            model="gpt-4o",
            scheme_and_host="https://api.openai.com",
            prompt="OCR the full page to markdown.",
            response_format=ResponseFormat.MARKDOWN,
            api_key=env['OPENAI_API_KEY'],
        ),
    )

    converter = DocumentConverter(
        format_options={
            InputFormat.PDF: PdfFormatOption(
                pipeline_options=pdf_pipeline_options,
                pipeline_cls=VlmPipeline,
            ),
        }
    )
    return converter

Docling version

Docling version: 2.57.0 Docling Core version: 2.48.4 Docling IBM Models version: 3.9.1 Docling Parse version: 4.5.0 Python: cpython-313 (3.13.7) Platform: Windows-11-10.0.26100-SP0

Python version

Python 3.13.7

Stack trace:

Traceback (most recent call last):
  File "D:\.venv-local-cpu\Lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 409, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        self.scope, self.receive, self.send
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "D:\.venv-local-cpu\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\.venv-local-cpu\Lib\site-packages\fastapi\applications.py", line 1133, in __call__
    await super().__call__(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
    raise exc
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "D:\.venv-local-cpu\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\routing.py", line 716, in __call__
    await self.middleware_stack(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\routing.py", line 736, in app
    await route.handle(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\routing.py", line 290, in handle
    await self.app(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\fastapi\routing.py", line 123, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "D:\.venv-local-cpu\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "D:\.venv-local-cpu\Lib\site-packages\fastapi\routing.py", line 109, in app
    response = await f(request)
               ^^^^^^^^^^^^^^^^
  File "D:\.venv-local-cpu\Lib\site-packages\fastapi\routing.py", line 389, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<3 lines>...
    )
    ^
  File "D:\.venv-local-cpu\Lib\site-packages\fastapi\routing.py", line 288, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\app\main.py", line 84, in chunk_document
    doc_id, chunk_snippets, time_elapsed = await doc_service.chunk_document(file, max_tokens, overlap, session)
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\app\services\document_service.py", line 68, in chunk_document
    result: ConversionResult = converter.convert(source=tmp_path)
                               ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "D:\.venv-local-cpu\Lib\site-packages\pydantic\_internal\_validate_call.py", line 39, in wrapper_function
    return wrapper(*args, **kwargs)
  File "D:\.venv-local-cpu\Lib\site-packages\pydantic\_internal\_validate_call.py", line 136, in __call__
    res = self.__pydantic_validator__.validate_python(pydantic_core.ArgsKwargs(args, kwargs))
  File "D:\.venv-local-cpu\Lib\site-packages\docling\document_converter.py", line 245, in convert
    return next(all_res)
  File "D:\.venv-local-cpu\Lib\site-packages\docling\document_converter.py", line 268, in convert_all
    for conv_res in conv_res_iter:
                    ^^^^^^^^^^^^^
  File "D:\.venv-local-cpu\Lib\site-packages\docling\document_converter.py", line 340, in _convert
    for item in map(
                ~~~^
        process_func,
        ^^^^^^^^^^^^^
        input_batch,
        ^^^^^^^^^^^^
    ):
    ^
  File "D:\.venv-local-cpu\Lib\site-packages\docling\document_converter.py", line 387, in _process_document
    conv_res = self._execute_pipeline(in_doc, raises_on_error=raises_on_error)
  File "D:\.venv-local-cpu\Lib\site-packages\docling\document_converter.py", line 410, in _execute_pipeline
    conv_res = pipeline.execute(in_doc, raises_on_error=raises_on_error)
  File "D:\.venv-local-cpu\Lib\site-packages\docling\pipeline\base_pipeline.py", line 80, in execute
    raise e
  File "D:\.venv-local-cpu\Lib\site-packages\docling\pipeline\base_pipeline.py", line 73, in execute
    conv_res = self._assemble_document(conv_res)
  File "D:\.venv-local-cpu\Lib\site-packages\docling\pipeline\vlm_pipeline.py", line 148, in _assemble_document
    conv_res.document = self._turn_md_into_doc(conv_res)
                        ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "D:\.venv-local-cpu\Lib\site-packages\docling\pipeline\vlm_pipeline.py", line 301, in _turn_md_into_doc
    conv_res.document.append_child_item(child=item)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "D:\.venv-local-cpu\Lib\site-packages\docling_core\types\doc\document.py", line 2017, in append_child_item
    raise ValueError("Can not append a child with children")
ValueError: Can not append a child with children

Contributor guide