{"record":{"id":"4354c5cbd4f3a234","repo":"docling-project/docling","slug":"cannot-specify-both-layout-preset-and-layout-custo","errorCode":null,"errorMessage":"Cannot specify both layout_preset and layout_custom_config.","messagePattern":"Cannot specify both layout_preset and layout_custom_config\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/datamodel/service/options.py","lineNumber":1080,"sourceCode":"        # when the fields are set, not here in the model validator\n\n        return self\n\n    @model_validator(mode=\"after\")\n    def validate_code_formula_options(self) -> Self:\n        \"\"\"Ensure preset and custom config are mutually exclusive for code/formula.\"\"\"\n        if self.code_formula_preset and self.code_formula_custom_config:\n            raise ValueError(\n                \"Cannot specify both code_formula_preset and code_formula_custom_config.\"\n            )\n\n        return self\n\n    @model_validator(mode=\"after\")\n    def validate_layout_options(self) -> Self:\n        \"\"\"Ensure preset and custom config are mutually exclusive for layout.\"\"\"\n        if self.layout_preset and self.layout_custom_config:\n            raise ValueError(\n                \"Cannot specify both layout_preset and layout_custom_config.\"\n            )\n        return self\n\n    @model_validator(mode=\"after\")\n    def validate_picture_classification_options(self) -> Self:\n        \"\"\"Ensure preset and custom config are mutually exclusive for picture classification.\"\"\"\n        if (\n            self.picture_classification_preset\n            and self.picture_classification_custom_config\n        ):\n            raise ValueError(\n                \"Cannot specify both picture_classification_preset and \"\n                \"picture_classification_custom_config.\"\n            )\n        return self\n\n    @model_validator(mode=\"after\")","sourceCodeStart":1062,"sourceCodeEnd":1098,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/datamodel/service/options.py#L1062-L1098","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nopts = ConvertOptions(\n    layout_preset=\"precise\",\n    layout_custom_config={\"do smash\": False},\n)\n\n# after\nopts = ConvertOptions(\n    layout_preset=\"precise\",\n)","handlingStrategy":"validation","validationCode":"def assert_layout(opts: dict) -> None:\n    assert not (opts.get(\"layout_preset\") and opts.get(\"layout_custom_config\")), (\n        \"layout_preset and layout_custom_config are mutually exclusive\"\n    )","typeGuard":null,"tryCatchPattern":"try:\n    ConvertOptions(**cfg)\nexcept ValidationError as e:\n    if \"layout_preset\" in str(e):\n        raise ValueError(\"Config sets both layout preset and custom config; remove one\") from e\n    raise","preventionTips":["Lint CI configs for forbidden key pairs (preset + custom_config).","Document in your config template that the two fields are alternatives."],"tags":["pydantic","validation","configuration","layout","mutually-exclusive"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}