{"record":{"id":"667c5d637f4bc30a","repo":"docling-project/docling","slug":"cannot-specify-both-code-formula-preset-and-code-f","errorCode":null,"errorMessage":"Cannot specify both code_formula_preset and code_formula_custom_config.","messagePattern":"Cannot specify both code_formula_preset and code_formula_custom_config\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/datamodel/service/options.py","lineNumber":1070,"sourceCode":"        )\n\n        if legacy_set and new_set:\n            raise ValueError(\n                \"Cannot mix legacy picture description options (picture_description_local/api) \"\n                \"with new options (picture_description_preset/custom_config). \"\n                \"Please use only one approach.\"\n            )\n\n        # Note: Deprecation warnings are now emitted by field validators\n        # 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 (","sourceCodeStart":1052,"sourceCodeEnd":1088,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/datamodel/service/options.py#L1052-L1088","documentation":"A Pydantic model validator on the service conversion options rejects configurations that set both code_formula_preset and code_formula_custom_config. These two fields are the preset-based and fully-custom ways to configure the code/formula stage, and they are mutually exclusive by design. The error is raised at model validation time, so it fires as soon as the options object is constructed.","triggerScenarios":"Constructing the service request options with both code_formula_preset (a string preset id) and code_formula_custom_config (a dict/model) set, e.g. options = ServiceOptions(code_formula_preset='accurate', code_formula_custom_config={...}). Any payload sent to the service that includes both keys fails validation with this message.","commonSituations":"Copy-pasting a config snippet that already had a preset and then adding custom tweaks on top; migrating from presets to custom config without removing the old key; JSON payloads where a default preset is merged in by a template system.","solutions":["Pick one approach: delete code_formula_custom_config and keep the preset, or delete code_formula_preset and keep the custom config.","If you only need small tweaks on top of a preset, check whether the preset id plus per-field overrides elsewhere are enough instead of a full custom config.","Audit your payload builder / template for code that merges default keys so both fields never co-occur."],"exampleFix":"# before\nopts = ConvertOptions(\n    code_formula_preset=\"accurate\",\n    code_formula_custom_config={\"some\": \"tweak\"},\n)\n\n# after\nopts = ConvertOptions(\n    code_formula_preset=\"accurate\",\n)","handlingStrategy":"validation","validationCode":"def assert_code_formula(opts: dict) -> None:\n    assert not (opts.get(\"code_formula_preset\") and opts.get(\"code_formula_custom_config\")), (\n        \"code_formula_preset and code_formula_custom_config are mutually exclusive\"\n    )","typeGuard":null,"tryCatchPattern":"try:\n    opts = ConvertOptions(**payload)\nexcept ValidationError as e:\n    if \"code_formula_preset\" in str(e):\n        payload.pop(\"code_formula_custom_config\", None)\n        opts = ConvertOptions(**payload)\n    else:\n        raise","preventionTips":["Model configs with exactly one of preset/custom_config per stage at the type level (a union type).","Build payloads through a helper that refuses to set both fields."],"tags":["pydantic","validation","configuration","code-formula","mutually-exclusive"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}