infiniflow/ragflow · critical · ValueError

Invalid config file: "{global_config_path}".

Error message

Invalid config file: "{global_config_path}".

What it means

ValueError raised by read_config in common/config_utils.py:66-69. The main configuration file conf/service_conf.yaml must be a YAML mapping at its root; if it parses to a list, scalar, or null (empty file parses to None, which is not a dict), startup aborts. Because CONFIGS = read_config() executes at import time of common.config_utils, every service entrypoint (API server, task executor) crashes on import when this fires.

Source

Thrown at common/config_utils.py:69

    conf_path = f"conf/{conf_name}"
    return os.path.join(get_project_base_directory(), conf_path)


def read_config(conf_name=SERVICE_CONF):
    local_config = {}
    local_path = conf_realpath(f"local.{conf_name}")

    # load local config file
    if os.path.exists(local_path):
        local_config = load_yaml_conf(local_path)
        if not isinstance(local_config, dict):
            raise ValueError(f'Invalid config file: "{local_path}".')

    global_config_path = conf_realpath(conf_name)
    global_config = load_yaml_conf(global_config_path)

    if not isinstance(global_config, dict):
        raise ValueError(f'Invalid config file: "{global_config_path}".')

    global_config.update(local_config)
    return global_config


CONFIGS = read_config()


def show_configs():
    msg = f"Current configs, from {conf_realpath(SERVICE_CONF)}:"
    for k, v in CONFIGS.items():
        if isinstance(v, dict):
            if "password" in v:
                v = copy.deepcopy(v)
                v["password"] = "*" * 8
            if "access_key" in v:
                v = copy.deepcopy(v)
                v["access_key"] = "*" * 8

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Fix conf/service_conf.yaml so the top level is key: value pairs only (no leading dashes, file not empty).
  2. Verify with: python -c "import yaml;d=yaml.safe_load(open('conf/service_conf.yaml'));print(type(d))" — must be <class 'dict'>.
  3. If the file is empty, restore it from git (git checkout -- conf/service_conf.yaml) and reapply your changes.

Example fix

# before: empty or list-rooted service_conf.yaml
- es:
    hosts: es01:9200
# after
es:
  hosts: es01:9200
Defensive patterns

Strategy: validation

Validate before calling

import yaml
with open("conf/service_conf.yaml") as f:
    data = yaml.safe_load(f)
assert isinstance(data, dict), "service_conf.yaml root must be a mapping"

Type guard

def is_valid_service_conf(path: str) -> bool:
    import yaml
    with open(path) as f:
        return isinstance(yaml.safe_load(f), dict)

Try / catch

try:
    import common.config_utils
except ValueError as e:
    if "Invalid config file" in str(e):
        path = str(e).split('"')[1]  # extract offending path from the message
        restore_or_fix(path)
    raise

Prevention

When it happens

Trigger: Editing conf/service_conf.yaml so its root is not a mapping: top-level list items, a file containing only comments (parses to None), or a mangled/truncated file. Any process that imports common.config_utils then fails during startup.

Common situations: Bad merge or rebase leaving stray '- ' prefixes; template substitution leaving the file empty; hand-editing under time pressure and breaking indentation so the document root becomes a list; mounting an empty file over conf/service_conf.yaml in docker.

Related errors


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