docling-project/docling · error · ValueError

The parameters vlm_pipeline_model, vlm_pipeline_model_local

Error message

The parameters vlm_pipeline_model, vlm_pipeline_model_local and vlm_pipeline_model_api are mutually exclusive, only one of them can be set.

What it means

Model validator on the service options: vlm_pipeline_model, vlm_pipeline_model_local, and vlm_pipeline_model_api are three mutually exclusive ways to specify the VLM pipeline model (legacy generic, local, API). Setting more than one raises this error because the service cannot decide which model source to use.

Source

Thrown at docling/datamodel/service/options.py:998

            raise ValueError(
                "The parameters picture_description_local and picture_description_api are mutually exclusive, only one of them can be set."
            )

        return self

    @model_validator(mode="after")
    def vlm_model_exclusivity(self) -> Self:
        # Validate vlm model options
        num_not_nan = sum(
            opt is not None
            for opt in (
                self.vlm_pipeline_model,
                self.vlm_pipeline_model_local,
                self.vlm_pipeline_model_api,
            )
        )
        if num_not_nan > 1:
            raise ValueError(
                "The parameters vlm_pipeline_model, vlm_pipeline_model_local and vlm_pipeline_model_api are mutually exclusive, only one of them can be set."
            )

        return self

    @model_validator(mode="after")
    def validate_vlm_pipeline_options(self) -> Self:
        """Ensure preset and custom config are mutually exclusive for VLM pipeline."""
        if self.vlm_pipeline_preset and self.vlm_pipeline_custom_config:
            raise ValueError(
                "Cannot specify both vlm_pipeline_preset and vlm_pipeline_custom_config. "
                "Please use one or the other."
            )

        # Check if using legacy fields with new fields
        legacy_set = (
            self.vlm_pipeline_model is not None
            or self.vlm_pipeline_model_local is not None

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Keep exactly one of vlm_pipeline_model, vlm_pipeline_model_local, vlm_pipeline_model_api.
  2. The vlm_pipeline_model* fields are legacy — consider migrating to vlm_pipeline_preset or vlm_pipeline_custom_config.
  3. Sanitize request payloads by stripping unused model keys before sending.

Example fix

# before
{'vlm_pipeline_model': 'smoldocling', 'vlm_pipeline_model_local': {...}}  # ValueError

# after
{'vlm_pipeline_model_local': {...}}
Defensive patterns

Strategy: validation

Validate before calling

VLM_MODEL_KEYS = ('vlm_pipeline_model', 'vlm_pipeline_model_local', 'vlm_pipeline_model_api')

def vlm_model_fields_ok(o: dict) -> bool:
    return sum(o.get(k) is not None for k in VLM_MODEL_KEYS) <= 1

Prevention

When it happens

Trigger: Options payloads containing two or three of the vlm_pipeline_model* keys, e.g., after merging a base config that sets vlm_pipeline_model with a request that adds vlm_pipeline_model_local.

Common situations: Legacy configs from older service versions (plain vlm_pipeline_model) combined with newer per-deployment local/API fields; copy-pasted examples stacking multiple model fields.

Related errors


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