{"record":{"id":"d4ff448215fb6d6b","repo":"infiniflow/ragflow","slug":"cpn-name-has-redundant-parameters-redundan","errorCode":null,"errorMessage":"cpn `{name}` has redundant parameters: `{[redundant_attrs]}`","messagePattern":"cpn `(.+?)` has redundant parameters: `(.+?)`","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/component/base.py","lineNumber":184,"sourceCode":"                    # add user feeded params\n                    user_feeded_params_set.add(full_config_key)\n\n                    # update user feeded deprecated param set\n                    if full_config_key in deprecated_params_set:\n                        feeded_deprecated_params_set.add(full_config_key)\n\n                # supported attr\n                attr = getattr(param, config_key)\n                if type(attr).__name__ in dir(builtins) or attr is None:\n                    setattr(param, config_key, config_value)\n\n                else:\n                    # recursive set obj attr\n                    sub_params = _recursive_update_param(attr, config_value, depth + 1, prefix=f\"{prefix}{config_key}.\")\n                    setattr(param, config_key, sub_params)\n\n            if not allow_redundant and redundant_attrs:\n                raise ValueError(f\"cpn `{getattr(self, '_name', type(self))}` has redundant parameters: `{[redundant_attrs]}`\")\n\n            return param\n\n        return _recursive_update_param(param=self, config=conf, depth=0, prefix=\"\")\n\n    def extract_not_builtin(self):\n        def _get_not_builtin_types(obj):\n            ret_dict = {}\n            for variable in obj.__dict__:\n                attr = getattr(obj, variable)\n                if attr and type(attr).__name__ not in dir(builtins):\n                    ret_dict[variable] = _get_not_builtin_types(attr)\n\n            return ret_dict\n\n        return _get_not_builtin_types(self)\n\n    def validate(self):","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/component/base.py#L166-L202","documentation":"After recursively applying a config to a component's param object, any config keys that do not correspond to declared attributes are collected as 'redundant'. When allow_redundant is false, their presence raises this ValueError naming the component and the extra keys — a strict schema check for component params.","triggerScenarios":"Calling param update (agent/component/base.py:184) with a config containing keys not declared on the param class — e.g. passing provider params to the wrong component type, or a config saved by an older/newer component version whose param class added/removed fields.","commonSituations":"Workflow JSON from a different RAGFlow version than the running server (param fields renamed); copy-pasting params between component types; hand-editing params with typos in key names; frontend form serialized with extra metadata keys.","solutions":["Compare the redundant key names in the error against the component's current Param class; rename or remove them.","If the workflow came from another version, re-create the node in the current UI rather than importing raw JSON.","Strip metadata/extra keys from the config before update if they are not component params.","For forward-compatible loading, pass allow_redundant=True only as a deliberate migration choice, not a blanket fix."],"exampleFix":"# before\nconf = {\"llm_id\": \"x\", \"temprature\": 0.7}  # typo'd key -> redundant\n\n# after\nconf = {\"llm_id\": \"x\", \"temperature\": 0.7}","handlingStrategy":"type-guard","validationCode":"def strip_unknown_keys(conf, param_obj):\n    declared = set(vars(param_obj).keys())\n    return {k: v for k, v in conf.items() if k in declared}","typeGuard":"def keys_are_declared(conf, param_obj) -> bool:\n    declared = set(vars(param_obj).keys())\n    return set(conf.keys()) <= declared","tryCatchPattern":"try:\n    param.update(conf)\nexcept ValueError as e:\n    if 'redundant parameters' in str(e):\n        conf = strip_unknown_keys(conf, param)\n        param.update(conf)  # retry only as deliberate migration","preventionTips":["Validate imported workflow JSON against the current component param classes before loading.","After version upgrades, migrate old canvases through the UI re-save path.","In generated configs, derive keys from the param class, not from string literals."],"tags":["canvas","schema-mismatch","parameter-validation","version-skew"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}