docling-project/docling · error · NotImplementedError

Label must be either code or formula

Error message

Label must be either code or formula

What it means

The code/formula recognition model maps an element label to a special query token: only the labels 'code' and 'formula' are valid, producing '<code>' or '<formula>'. Any other label reaches the else branch and raises NotImplementedError. It is a programming-contract error: the stage is only designed to process CodeItem and FormulaItem elements.

Source

Thrown at docling/models/stages/code_formula/code_formula_model.py:237

        label : str
            The type of input, either 'code' or 'formula'.

        Returns
        -------
        str
            The constructed prompt including necessary tokens and query.

        Raises
        ------
        NotImplementedError
            If the label is not 'code' or 'formula'.
        """
        if label == "code":
            query = "<code>"
        elif label == "formula":
            query = "<formula>"
        else:
            raise NotImplementedError("Label must be either code or formula")

        messages = [
            {
                "role": "user",
                "content": [{"type": "image"}, {"type": "text", "text": query}],
            },
        ]

        prompt = self._processor.apply_chat_template(
            messages, add_generation_prompt=True
        )

        return prompt

    def _post_process(self, texts: list[str]) -> list[str]:
        """
        Processes a list of text strings by truncating at '<end_of_utterance>' and
        removing a predefined set of unwanted substrings.

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Filter the batch before the stage so only items with label 'code' or 'formula' are passed (the standard pipeline does this).
  2. Check for exact lowercase strings; normalize labels (item.label.lower().strip()) if labels come from custom code.
  3. If you genuinely need a new label handled, subclass or extend the model — do not pass unsupported labels.

Example fix

# before
for el in element_batch:
    query = self._get_query(el.item.label)  # raises for 'paragraph'

# after
for el in element_batch:
    if el.item.label not in ("code", "formula"):
        continue
    query = self._get_query(el.item.label)
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_LABELS = {"code", "formula"}
batch = [el for el in element_batch if el.item.label in SUPPORTED_LABELS]

Type guard

from typing import TypeGuard

def is_supported_label(label: str) -> TypeGuard[str]:
    return label in ("code", "formula")

Try / catch

try:
    query = self._get_query(item.label)
except NotImplementedError:
    _log.debug("Skipping unsupported label %r", item.label)
    return

Prevention

When it happens

Trigger: Calling _get_query (or feeding the model a batch) with an element whose .label is neither exactly 'code' nor 'formula' — e.g. 'CodeItem', 'formula ' (case/whitespace), or a text label like 'paragraph' reaching this stage due to a filtering bug upstream.

Common situations: Custom pipelines that route all items through the code/formula stage without filtering by label; label strings that differ in case or use item-class names instead of the enum values; upgrading docling where label enum values changed.

Related errors


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