{"record":{"id":"d64939e54e98e811","repo":"docling-project/docling","slug":"cannot-mix-legacy-vlm-options-vlm-pipeline-model","errorCode":null,"errorMessage":"Cannot mix legacy VLM options (vlm_pipeline_model*) with new options (vlm_pipeline_preset/custom_config). Please use only one approach.","messagePattern":"Cannot mix legacy VLM options \\(vlm_pipeline_model\\*\\) with new options \\(vlm_pipeline_preset/custom_config\\)\\. Please use only one approach\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"docling/datamodel/service/options.py","lineNumber":1025,"sourceCode":"        if self.vlm_pipeline_preset and self.vlm_pipeline_custom_config:\n            raise ValueError(\n                \"Cannot specify both vlm_pipeline_preset and vlm_pipeline_custom_config. \"\n                \"Please use one or the other.\"\n            )\n\n        # Check if using legacy fields with new fields\n        legacy_set = (\n            self.vlm_pipeline_model is not None\n            or self.vlm_pipeline_model_local is not None\n            or self.vlm_pipeline_model_api is not None\n        )\n        new_set = (\n            self.vlm_pipeline_preset is not None\n            or self.vlm_pipeline_custom_config is not None\n        )\n\n        if legacy_set and new_set:\n            raise ValueError(\n                \"Cannot mix legacy VLM options (vlm_pipeline_model*) with new options \"\n                \"(vlm_pipeline_preset/custom_config). 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_picture_description_options(self) -> Self:\n        \"\"\"Ensure preset and custom config are mutually exclusive for picture description.\"\"\"\n        if self.picture_description_preset and self.picture_description_custom_config:\n            raise ValueError(\n                \"Cannot specify both picture_description_preset and \"\n                \"picture_description_custom_config.\"\n            )\n","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/datamodel/service/options.py#L1007-L1043","documentation":"Model validator on the service options: the legacy VLM model fields (vlm_pipeline_model, vlm_pipeline_model_local, vlm_pipeline_model_api) cannot be combined with the new-style fields (vlm_pipeline_preset, vlm_pipeline_custom_config). Docling migrated VLM configuration to presets/custom configs, and mixing generations of the API is rejected to avoid ambiguity.","triggerScenarios":"Options carrying any vlm_pipeline_model* key together with vlm_pipeline_preset or vlm_pipeline_custom_config — e.g., an old client config (model fields) sent to an upgraded service that also injects a preset, or a config migration done halfway.","commonSituations":"Upgrading a docling-service deployment: existing request payloads still contain legacy vlm_pipeline_model while the new deployment templates add presets; client libraries lagging behind service version.","solutions":["Migrate fully to the new style: remove all vlm_pipeline_model* keys and keep only vlm_pipeline_preset or vlm_pipeline_custom_config.","If you must stay on the legacy API temporarily, ensure no preset/custom_config keys are present.","Add a client-side check that rejects payloads containing keys from both generations before submission."],"exampleFix":"# before\n{'vlm_pipeline_model': 'smoldocling', 'vlm_pipeline_preset': 'vlm'}  # ValueError\n\n# after\n{'vlm_pipeline_preset': 'vlm'}","handlingStrategy":"validation","validationCode":"LEGACY = ('vlm_pipeline_model', 'vlm_pipeline_model_local', 'vlm_pipeline_model_api')\nNEW = ('vlm_pipeline_preset', 'vlm_pipeline_custom_config')\n\ndef vlm_generations_not_mixed(o: dict) -> bool:\n    return not (any(o.get(k) is not None for k in LEGACY)\n                and any(o.get(k) is not None for k in NEW))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Complete config migration in one step: all-new keys or all-legacy keys, never mixed.","Add a payload lint step that rejects mixed-generation VLM keys.","Track docling service release notes for config API migrations."],"tags":["service","vlm","validation","migration","deprecation"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}