docling-project/docling · error · ValueError
Cannot specify both vlm_pipeline_preset and vlm_pipeline_cus
Error message
Cannot specify both vlm_pipeline_preset and vlm_pipeline_custom_config. Please use one or the other.
What it means
Model validator on the service options: vlm_pipeline_preset (a named preset) and vlm_pipeline_custom_config (a full custom configuration) are the two new-style ways to configure the VLM pipeline and are mutually exclusive — a preset already fixes the config, so supplying both is contradictory.
Source
Thrown at docling/datamodel/service/options.py:1008
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
or self.vlm_pipeline_model_api is not None
)
new_set = (
self.vlm_pipeline_preset is not None
or self.vlm_pipeline_custom_config is not None
)
if legacy_set and new_set:
raise ValueError(
"Cannot mix legacy VLM options (vlm_pipeline_model*) with new options "View on GitHub (pinned to 61d76f1ff3)
Solutions
- Choose one: either the preset name or the fully custom config object.
- If you need to tweak a preset, copy its contents into vlm_pipeline_custom_config, modify, and drop the preset field.
- Strip default preset values from templates before adding custom configs.
Example fix
# before
{'vlm_pipeline_preset': 'vlm', 'vlm_pipeline_custom_config': {...}} # ValueError
# after
{'vlm_pipeline_custom_config': {...}} Defensive patterns
Strategy: validation
Validate before calling
def vlm_preset_exclusive(o: dict) -> bool:
return not (o.get('vlm_pipeline_preset') and o.get('vlm_pipeline_custom_config')) Prevention
- Choose preset or custom_config, never both.
- To tweak a preset, copy it into a custom_config and drop the preset key.
- Keep base templates free of defaults that collide with per-request overrides.
When it happens
Trigger: Request options containing both vlm_pipeline_preset='...' and vlm_pipeline_custom_config={...}, typically from a config template that fills a default preset while code adds a custom config for tuning.
Common situations: Teams sharing a base options JSON with a preset, then developers layering custom_config tweaks on top instead of forking the preset.
Related errors
- The parameters vlm_pipeline_model, vlm_pipeline_model_local
- The parameters picture_description_local and picture_descrip
- Cannot mix legacy VLM options (vlm_pipeline_model*) with new
- Cannot specify both picture_description_preset and picture_d
- set either layout or layout_file, not both
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/398e3b53e316d901.
Report an issue: GitHub.