{"record":{"id":"acfc56f8a0ec4f4e","repo":"docling-project/docling","slug":"cannot-specify-both-chunking-preset-and-chunking-o","errorCode":null,"errorMessage":"Cannot specify both chunking_preset and chunking_options.","messagePattern":"Cannot specify both chunking_preset and chunking_options\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/datamodel/service/options.py","lineNumber":1125,"sourceCode":"            warnings.warn(\n                \"ocr_engine is deprecated and will be removed in a future version. \"\n                \"Use ocr_preset instead.\",\n                DeprecationWarning,\n                stacklevel=2,\n            )\n            # Sync ocr_engine value to ocr_preset only if ocr_preset wasn't explicitly set\n            object.__setattr__(self, \"ocr_preset\", self.ocr_engine)\n\n        # Ensure preset and custom_config are mutually exclusive\n        if self.ocr_preset != \"auto\" and self.ocr_custom_config:\n            raise ValueError(\"Cannot specify both ocr_preset and ocr_custom_config.\")\n\n        return self\n\n    @model_validator(mode=\"after\")\n    def validate_chunking_options(self) -> Self:\n        if self.chunking_preset and self.chunking_options is not None:\n            raise ValueError(\n                \"Cannot specify both chunking_preset and chunking_options.\"\n            )\n\n        return self\n","sourceCodeStart":1107,"sourceCodeEnd":1130,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/datamodel/service/options.py#L1107-L1130","documentation":"The validate_chunking_options model validator rejects options that set both chunking_preset and chunking_options. Chunking is configured either by a named preset or by an explicit options object, never both. The check uses `is not None` against chunking_options, so any non-None chunking_options together with a truthy preset raises.","triggerScenarios":"Constructing options with chunking_preset='aggressive' and chunking_options=HybridChunkerOptions(...) (or a dict) at the same time, e.g. in a service request payload or the SDK options model.","commonSituations":"Taking a preset from documentation and adding explicit chunking parameters for RAG tuning; config files where chunking_options was set previously and a chunking_preset line was appended later; forgetting that the preset already encapsulates chunker settings.","solutions":["Keep exactly one: chunking_preset for a named configuration, chunking_options for explicit control.","If you set chunking_options to the preset's defaults and tweaked one field, remove the preset and keep only chunking_options.","Grep your config/JSON for both keys appearing in the same section."],"exampleFix":"# before\nopts = ConvertOptions(\n    chunking_preset=\"aggressive\",\n    chunking_options=HybridChunkerOptions(merge_peers=True),\n)\n\n# after\nopts = ConvertOptions(\n    chunking_options=HybridChunkerOptions(merge_peers=True),\n)","handlingStrategy":"validation","validationCode":"def assert_chunking(opts: dict) -> None:\n    assert not (opts.get(\"chunking_preset\") and opts.get(\"chunking_options\") is not None), (\n        \"chunking_preset and chunking_options are mutually exclusive\"\n    )","typeGuard":null,"tryCatchPattern":"try:\n    ConvertOptions(**cfg)\nexcept ValidationError as e:\n    if \"chunking\" in str(e):\n        raise ValueError(\"Set only chunking_preset or chunking_options, not both\") from e\n    raise","preventionTips":["When migrating from presets to explicit chunker options, delete the preset key in the same commit.","Validate config files against a schema encoding the mutual exclusion."],"tags":["pydantic","validation","chunking","configuration","mutually-exclusive"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}