docling-project/docling · error · ValueError
Cannot specify both layout_preset and layout_custom_config.
Error message
Cannot specify both layout_preset and layout_custom_config.
What it means
A Pydantic model validator on the service conversion options rejects configurations that set both layout_preset and layout_custom_config. The layout stage accepts either a named preset or a fully custom configuration dictionary, never both. Validation happens at options construction time.
Source
Thrown at docling/datamodel/service/options.py:1080
# when the fields are set, not here in the model validator
return self
@model_validator(mode="after")
def validate_code_formula_options(self) -> Self:
"""Ensure preset and custom config are mutually exclusive for code/formula."""
if self.code_formula_preset and self.code_formula_custom_config:
raise ValueError(
"Cannot specify both code_formula_preset and code_formula_custom_config."
)
return self
@model_validator(mode="after")
def validate_layout_options(self) -> Self:
"""Ensure preset and custom config are mutually exclusive for layout."""
if self.layout_preset and self.layout_custom_config:
raise ValueError(
"Cannot specify both layout_preset and layout_custom_config."
)
return self
@model_validator(mode="after")
def validate_picture_classification_options(self) -> Self:
"""Ensure preset and custom config are mutually exclusive for picture classification."""
if (
self.picture_classification_preset
and self.picture_classification_custom_config
):
raise ValueError(
"Cannot specify both picture_classification_preset and "
"picture_classification_custom_config."
)
return self
@model_validator(mode="after")View on GitHub (pinned to 61d76f1ff3)
Solutions
- Remove one of the two keys: keep layout_preset for named presets or layout_custom_config for bespoke settings.
- If you used the custom config only to reproduce a preset, drop it and rely on the preset id.
- Add an assertion in your config loader that at most one of the pair is present before submitting.
Example fix
# before
opts = ConvertOptions(
layout_preset="precise",
layout_custom_config={"do smash": False},
)
# after
opts = ConvertOptions(
layout_preset="precise",
) Defensive patterns
Strategy: validation
Validate before calling
def assert_layout(opts: dict) -> None:
assert not (opts.get("layout_preset") and opts.get("layout_custom_config")), (
"layout_preset and layout_custom_config are mutually exclusive"
) Try / catch
try:
ConvertOptions(**cfg)
except ValidationError as e:
if "layout_preset" in str(e):
raise ValueError("Config sets both layout preset and custom config; remove one") from e
raise Prevention
- Lint CI configs for forbidden key pairs (preset + custom_config).
- Document in your config template that the two fields are alternatives.
When it happens
Trigger: Passing both layout_preset and layout_custom_config in the options model, e.g. ConvertOptions(layout_preset='precise', layout_custom_config={'threshold': 0.4}). The validator validate_layout_options raises immediately after the model is built.
Common situations: Starting from a preset-based config and layering a custom layout dict on top; CI configs assembled from multiple YAML fragments that each contribute one of the two keys; upgrading docling versions where options were renamed from a single field into the preset/custom pair.
Related errors
- Cannot specify both code_formula_preset and code_formula_cus
- Cannot specify both picture_classification_preset and pictur
- Cannot specify both chunking_preset and chunking_options.
- Cannot specify both ocr_preset and ocr_custom_config.
- 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/4354c5cbd4f3a234.
Report an issue: GitHub.