docling-project/docling · error · RuntimeError

Invalid WebVTT document.

Error message

Invalid WebVTT document.

What it means

WebVTTBackend.convert() was called on a document that failed signature verification (content does not start with a valid WEBVTT header), so it raises RuntimeError instead of parsing garbage. In the normal DocumentConverter flow invalid backends are filtered out by format detection; this surfaces when convert() is invoked directly on an invalid backend.

Source

Thrown at docling/backend/webvtt_backend.py:104

    def supports_pagination(cls) -> bool:
        return False

    @override
    def unload(self):
        if isinstance(self.path_or_stream, BytesIO):
            self.path_or_stream.close()
        self.path_or_stream = None

    @classmethod
    @override
    def supported_formats(cls) -> set[InputFormat]:
        return {InputFormat.VTT}

    @override
    def convert(self) -> DoclingDocument:
        _log.debug("Starting WebVTT conversion...")
        if not self.is_valid():
            raise RuntimeError("Invalid WebVTT document.")

        origin = DocumentOrigin(
            filename=self.file.name or "file",
            mimetype="text/vtt",
            binary_hash=self.document_hash,
        )
        doc = DoclingDocument(name=self.file.stem or "file", origin=origin)

        vtt: WebVTTFile = WebVTTFile.parse(self.content)
        cue_text: list[AnnotatedPar] = []
        parents: list[AnnotatedText] = []

        def _extract_components(
            payload: list[WebVTTCueComponentWithTerminator],
        ) -> None:
            nonlocal cue_text, parents
            if not cue_text:
                cue_text.append(AnnotatedPar(items=[]))

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Ensure the file starts with 'WEBVTT' on the first line; convert SRT to VTT (change header, commas to dots in timestamps).
  2. Route conversion through DocumentConverter, which checks backend.is_valid() and reports an unsupported format instead of crashing.
  3. If using the backend directly, guard with `if backend.is_valid(): backend.convert()`.
  4. Strip a leading BOM or blank lines before the WEBVTT marker.

Example fix

# before
backend = WebVTTBackend(in_doc, path_or_stream)
doc = backend.convert()  # RuntimeError if invalid

# after
backend = WebVTTBackend(in_doc, path_or_stream)
if not backend.is_valid():
    raise ValueError("not a WebVTT document; convert SRT to VTT first")
doc = backend.convert()
Defensive patterns

Strategy: validation

Validate before calling

def is_probable_webvtt(content: str) -> bool:
    return content.lstrip("\ufeff\ufeff ").startswith("WEBVTT")

Try / catch

try:
    doc = backend.convert()
except RuntimeError as e:
    if "Invalid WebVTT" in str(e):
        raise ValueError("input is not WebVTT; convert SRT to VTT first") from e
    raise

Prevention

When it happens

Trigger: Constructing WebVTTBackend on a file whose content lacks the 'WEBVTT' magic (so is_valid() is False) and calling convert() anyway — e.g. manual backend usage, or a .vtt file that is actually SRT text.

Common situations: SRT files renamed to .vtt; empty or whitespace-prefixed caption files; custom code driving backends directly instead of DocumentConverter.

Related errors


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