docling-project/docling · error · RuntimeError

ASR pipeline requires a file path or BytesIO stream, but got

Error message

ASR pipeline requires a file path or BytesIO stream, but got {type(path_or_stream)}

What it means

The native-whisper transcriber's run() only accepts input streams of type BytesIO or Path, because whisper.load_model/transcribe needs a real file path (BytesIO is spilled to a NamedTemporaryFile). Any other object (plain file object, str path, bytes) raises RuntimeError with the received type.

Source

Thrown at docling/pipeline/asr_transcriber.py:303

    def run(self, conv_res: ConversionResult) -> ConversionResult:
        # Access the file path from the backend, similar to other pipelines
        path_or_stream = conv_res.input._backend.path_or_stream

        # Handle both Path and BytesIO inputs
        temp_file_path: Path | None = None

        if isinstance(path_or_stream, BytesIO):
            # For BytesIO, write to a temporary file (whisper needs a file path)
            suffix = Path(conv_res.input.file.name).suffix or ".wav"
            with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp_file:
                tmp_file.write(path_or_stream.getvalue())
                temp_file_path = Path(tmp_file.name)
            audio_path = temp_file_path
        elif isinstance(path_or_stream, Path):
            audio_path = path_or_stream
        else:
            raise RuntimeError(
                f"ASR pipeline requires a file path or BytesIO stream, "
                f"but got {type(path_or_stream)}"
            )

        try:
            if shutil.which("ffmpeg") is None:
                _log.error(MISSING_FFMPEG_MESSAGE)
                conv_res.errors.append(
                    ErrorItem(
                        component_type=DoclingComponentType.PIPELINE,
                        module_name="AsrPipeline",
                        error_message=MISSING_FFMPEG_MESSAGE,
                    )
                )
                conv_res.status = ConversionStatus.FAILURE
                return conv_res

            conversation = self.transcribe(audio_path)

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Wrap string paths in pathlib.Path before conversion: DocumentConverter().convert(Path('audio.mp3'))
  2. Wrap raw bytes in io.BytesIO(bytes_payload) so the transcriber spills it to a temp file itself
  3. For custom backends, make path_or_stream return Path or BytesIO

Example fix

# before
conv = converter.convert('meeting.wav')   # str -> RuntimeError

# after
from pathlib import Path
conv = converter.convert(Path('meeting.wav'))
Defensive patterns

Strategy: type-guard

Validate before calling

from io import BytesIO
from pathlib import Path

audio = Path('meeting.wav') if isinstance(audio, str) else audio
if not isinstance(audio, (Path, BytesIO)):
    audio = BytesIO(audio) if isinstance(audio, (bytes, bytearray)) else Path(audio)

Type guard

from io import BytesIO
from pathlib import Path
from typing import Any

def is_asr_input(x: Any) -> bool:
    return isinstance(x, (Path, BytesIO))

Prevention

When it happens

Trigger: Converting a document whose backend exposes path_or_stream as something other than BytesIO or pathlib.Path — e.g. passing a raw str filename to DocumentConverter, an opened file handle, or a custom InputDocument backend storing bytes.

Common situations: Calling DocumentConverter.convert('audio.mp3') with a string instead of Path('audio.mp3'); custom format backends that keep content as bytes or StringIO; wrappers that pass http response bodies directly.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/9821bdb3dd5670b7. Report an issue: GitHub.