docling-project/docling · error · ValueError
Cannot specify both ocr_preset and ocr_custom_config.
Error message
Cannot specify both ocr_preset and ocr_custom_config.
What it means
The OCR options validator rejects configurations that set both ocr_preset (any value other than the default 'auto') and ocr_custom_config. Note the special case: ocr_preset='auto' may coexist with a custom config, because 'auto' is treated as 'no explicit preset'. A deprecated ocr_engine field is synced into ocr_preset first, so setting ocr_engine alongside ocr_custom_config also triggers this.
Source
Thrown at docling/datamodel/service/options.py:1118
"""Handle deprecated ocr_engine and sync to ocr_preset."""
# If ocr_engine is explicitly set (not default), sync to ocr_preset
if (
hasattr(self, "__pydantic_fields_set__")
and "ocr_engine" in self.__pydantic_fields_set__
and "ocr_preset" not in self.__pydantic_fields_set__
):
warnings.warn(
"ocr_engine is deprecated and will be removed in a future version. "
"Use ocr_preset instead.",
DeprecationWarning,
stacklevel=2,
)
# Sync ocr_engine value to ocr_preset only if ocr_preset wasn't explicitly set
object.__setattr__(self, "ocr_preset", self.ocr_engine)
# Ensure preset and custom_config are mutually exclusive
if self.ocr_preset != "auto" and self.ocr_custom_config:
raise ValueError("Cannot specify both ocr_preset and ocr_custom_config.")
return self
@model_validator(mode="after")
def validate_chunking_options(self) -> Self:
if self.chunking_preset and self.chunking_options is not None:
raise ValueError(
"Cannot specify both chunking_preset and chunking_options."
)
return self
View on GitHub (pinned to 61d76f1ff3)
Solutions
- Remove ocr_preset (or set it to 'auto') and keep ocr_custom_config, or drop ocr_custom_config and keep the preset.
- If you still pass the deprecated ocr_engine, remove it — it is synced to ocr_preset and counts as specifying a preset.
- Prefer ocr_preset over ocr_engine in all new code to avoid the sync behavior surprising you.
Example fix
# before (also triggers via deprecated ocr_engine)
opts = ConvertOptions(
ocr_engine="tesseract",
ocr_custom_config={"force_full_page_ocr": True},
)
# after
opts = ConvertOptions(
ocr_preset="auto",
ocr_custom_config={"force_full_page_ocr": True},
) Defensive patterns
Strategy: validation
Validate before calling
def assert_ocr(opts: dict) -> None:
preset = opts.get("ocr_preset", opts.get("ocr_engine", "auto"))
assert preset == "auto" or not opts.get("ocr_custom_config"), (
"ocr_preset (including synced ocr_engine) conflicts with ocr_custom_config"
) Try / catch
try:
ConvertOptions(**cfg)
except ValidationError as e:
if "ocr_preset" in str(e):
cfg.setdefault("ocr_preset", "auto")
cfg.pop("ocr_engine", None)
opts = ConvertOptions(**cfg)
else:
raise Prevention
- Migrate off the deprecated ocr_engine entirely to avoid the silent sync into ocr_preset.
- Treat ocr_preset='auto' as 'no preset' when pairing with ocr_custom_config.
When it happens
Trigger: Passing ocr_preset='easyocr' together with ocr_custom_config={...}; or passing the deprecated ocr_engine='tesseract' together with ocr_custom_config, because the validator syncs ocr_engine into ocr_preset before the exclusivity check.
Common situations: Migrating old scripts that used ocr_engine to the new ocr_preset API while custom OCR settings are also present; presets used as a baseline with custom tweaks layered on; a deprecation warning was already emitted and the user half-migrated.
Related errors
- Cannot specify both code_formula_preset and code_formula_cus
- Cannot specify both layout_preset and layout_custom_config.
- Cannot specify both picture_classification_preset and pictur
- Cannot specify both chunking_preset and chunking_options.
- Invalid device option. Use `auto`, `cpu`, `mps`, `xpu`, `cud
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/29bbd2cd8236a8bc.
Report an issue: GitHub.