PaddlePaddle/PaddleOCR · error · ValueError
`{name}` and `{new_name}` are mutually exclusive.
Error message
`{name}` and `{new_name}` are mutually exclusive. What it means
PaddleOCR's constructor accepts deprecated parameter names (mapped via _DEPRECATED_PARAM_NAME_MAPPING, e.g. det_model_dir -> text_detection_model_dir, use_angle_cls -> use_textline_orientation). If you pass BOTH the deprecated name and its modern replacement, and the modern one is not None, it raises ValueError because the two would conflict. A deprecation warning is emitted first, then the conflict is detected.
Source
Thrown at paddleocr/_pipelines/ocr.py:164
"text_det_limit_type": text_det_limit_type,
"text_det_thresh": text_det_thresh,
"text_det_box_thresh": text_det_box_thresh,
"text_det_unclip_ratio": text_det_unclip_ratio,
"text_det_input_shape": text_det_input_shape,
"text_rec_score_thresh": text_rec_score_thresh,
"return_word_box": return_word_box,
"text_rec_input_shape": text_rec_input_shape,
}
base_params = {}
for name, val in kwargs.items():
if name in _DEPRECATED_PARAM_NAME_MAPPING:
new_name = _DEPRECATED_PARAM_NAME_MAPPING[name]
warn_deprecated_param(name, new_name)
assert (
new_name in params
), f"{repr(new_name)} is not a valid parameter name."
if params[new_name] is not None:
raise ValueError(
f"`{name}` and `{new_name}` are mutually exclusive."
)
params[new_name] = val
else:
base_params[name] = val
self._params = params
super().__init__(**base_params)
@property
def _paddlex_pipeline_name(self):
return "OCR"
def predict_iter(
self,
input,
*,View on GitHub (pinned to 2661c7c0ef)
Solutions
- Delete the deprecated parameter and keep only the modern one (see _DEPRECATED_PARAM_NAME_MAPPING for the exact rename table).
- If the modern param is at its default None, passing only the deprecated name still works — so just drop one of the two.
- Grep your config for the old names (det_model_dir, det_db_thresh, use_angle_cls, cls_model_dir, rec_batch_num, etc.) and migrate them.
Example fix
# before ocr = PaddleOCR(use_angle_cls=True, use_textline_orientation=True) # ValueError # after ocr = PaddleOCR(use_textline_orientation=True)
Defensive patterns
Strategy: validation
Validate before calling
from paddleocr._pipelines.ocr import _DEPRECATED_PARAM_NAME_MAPPING
def strip_deprecated_conflicts(cfg: dict) -> dict:
cfg = dict(cfg)
for old, new in _DEPRECATED_PARAM_NAME_MAPPING.items():
if old in cfg and cfg.get(new) is not None:
del cfg[old] # prefer the modern name
return cfg Prevention
- Migrate configs fully to the new parameter names in one pass
- Never carry both a name and its rename in shared config dicts
- Treat DeprecationWarnings as errors locally to catch leftover old names early
When it happens
Trigger: PaddleOCR(use_angle_cls=True, use_textline_orientation=True), PaddleOCR(det_model_dir='...', text_detection_model_dir='...'), or any pair in the mapping such as rec_batch_num together with text_recognition_batch_size where the new-name value is set.
Common situations: Migrating old sample code incrementally and ending up with both old and new kwargs; config files that accumulate options across paddleocr upgrades; tutorials mixing v2.x and v3.x parameter styles.
Related errors
- Invalid OCR version: {ocr_version}. Supported values are {_S
- No models are available for lang={lang} and ocr_version={ocr
- Invalid pipeline version: {pipeline_version}. Supported vers
- Invalid backend for the VL recognition module: {vl_rec_backe
- Invalid OCR version: {ocr_version}. Supported values are {_S
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/ef5995ac823e311c.
Report an issue: GitHub.