infiniflow/ragflow · error · ValueError

Param define nesting too deep!!!, can not parse it

Error message

Param define nesting too deep!!!, can not parse it

What it means

Component parameters are applied by recursively walking nested param objects and config dicts. A depth counter guards against pathological/cyclic structures; exceeding settings.PARAM_MAXDEPTH aborts with this ValueError before recursion blows the stack.

Source

Thrown at agent/component/base.py:149

            return ret_dict

        return _recursive_convert_obj_to_dict(self)

    def update(self, conf, allow_redundant=False):
        update_from_raw_conf = conf.get(_IS_RAW_CONF, True)
        if update_from_raw_conf:
            deprecated_params_set = self._get_or_init_deprecated_params_set()
            feeded_deprecated_params_set = self._get_or_init_feeded_deprecated_params_set()
            user_feeded_params_set = self._get_or_init_user_feeded_params_set()
            setattr(self, _IS_RAW_CONF, False)
        else:
            feeded_deprecated_params_set = self._get_or_init_feeded_deprecated_params_set(conf)
            user_feeded_params_set = self._get_or_init_user_feeded_params_set(conf)

        def _recursive_update_param(param, config, depth, prefix):
            if depth > settings.PARAM_MAXDEPTH:
                raise ValueError("Param define nesting too deep!!!, can not parse it")

            inst_variables = param.__dict__
            redundant_attrs = []
            for config_key, config_value in config.items():
                # redundant attr
                if config_key not in inst_variables:
                    if not update_from_raw_conf and config_key.startswith("_"):
                        setattr(param, config_key, config_value)
                    else:
                        setattr(param, config_key, config_value)
                        # redundant_attrs.append(config_key)
                    continue

                full_config_key = f"{prefix}{config_key}"

                if update_from_raw_conf:
                    # add user feeded params
                    user_feeded_params_set.add(full_config_key)

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Inspect the component config for cycles — most often a param dict that references an ancestor dict; break the cycle by deepcopying or restructuring.
  2. Flatten unnecessarily deep structures; component params rarely need more than a few levels.
  3. If a legitimate deep structure is required, raise settings.PARAM_MAXDEPTH deliberately (mind Python's recursion limit).
  4. Log the config (json.dumps with default=repr) at the failure point to see the actual depth/shape.

Example fix

# before
cfg['parent'] = cfg  # self-reference -> infinite recursion
component.update(cfg)

# after
import copy
cfg['parent'] = copy.deepcopy(cfg_summary)  # acyclic, shallow
component.update(cfg)
Defensive patterns

Strategy: validation

Validate before calling

def config_depth(conf):
    if not isinstance(conf, dict):
        return 0
    return 1 + max((config_depth(v) for v in conf.values()), default=0)

def safe_update(component, conf, maxdepth):
    if config_depth(conf) > maxdepth:
        raise ValueError('config nesting exceeds PARAM_MAXDEPTH')
    component.update(conf)

Type guard

def is_acyclic(conf):
    seen = set()
    stack = [conf]
    while stack:
        obj = stack.pop()
        if id(obj) in seen:
            return False
        seen.add(id(obj))
        if isinstance(obj, dict):
            stack.extend(obj.values())
        elif isinstance(obj, list):
            stack.extend(obj)
    return True

Try / catch

try:
    component.update(conf)
except ValueError as e:
    if 'nesting too deep' in str(e):
        conf = json.loads(json.dumps(conf, default=str))  # breaks cycles/normalizes
        component.update(conf)

Prevention

When it happens

Trigger: update()/load of a component config whose nesting depth exceeds settings.PARAM_MAXDEPTH — usually a config dict that (indirectly) contains itself, or a deeply nested legit structure from generated configs.

Common situations: Cyclic reference created by assigning a param object into its own sub-config; machine-generated configs with unbounded nesting; PARAM_MAXDEPTH lowered in settings; a config accidentally inlined multiple times (config containing a copy of the whole component including its config).

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/17e9380d5edda649. Report an issue: GitHub.