infiniflow/ragflow · error · EnvironmentError
rewrite yaml file config {} failed:
Error message
rewrite yaml file config {} failed: What it means
EnvironmentError raised by rewrite_yaml_conf in common/config_utils.py:41-48. This helper persists a config dict back to a YAML file (typically conf/service_conf.yaml or conf/local.service_conf.yaml, resolved relative to the project base directory when the path is not absolute). Any exception while opening the file for writing or dumping the YAML — permission denied, read-only mount, missing parent directory, or a config object containing non-serializable types for the safe dumper — is re-raised as EnvironmentError with the offending path in the message.
Source
Thrown at common/config_utils.py:47
if not os.path.isabs(conf_path):
conf_path = os.path.join(get_project_base_directory(), conf_path)
try:
with open(conf_path) as f:
yaml = YAML(typ="safe", pure=True)
return yaml.load(f)
except Exception as e:
raise EnvironmentError("loading yaml file config from {} failed:".format(conf_path), e)
def rewrite_yaml_conf(conf_path, config):
if not os.path.isabs(conf_path):
conf_path = os.path.join(get_project_base_directory(), conf_path)
try:
with open(conf_path, "w") as f:
yaml = YAML(typ="safe")
yaml.dump(config, f)
except Exception as e:
raise EnvironmentError("rewrite yaml file config {} failed:".format(conf_path), e)
def conf_realpath(conf_name):
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)View on GitHub (pinned to 554fb1133a)
Solutions
- Make the target YAML file and its directory writable by the service user: chown/chmod conf/ and conf/*.yaml.
- If the config volume is mounted read-only, remount it read-write or store runtime config elsewhere (e.g. rely on environment variables).
- Check the full exception chain (the original exception is passed as the second arg) to see whether it is an IO error or a YAML representation error.
- If it is a representation error, convert custom objects in the config to plain str/int/dict/list before calling rewrite_yaml_conf.
Example fix
# before: conf owned by root, service runs as ragflow user # after chown -R ragflow:ragflow /path/to/ragflow/conf chmod u+w /path/to/ragflow/conf/service_conf.yaml
Defensive patterns
Strategy: try-catch
Validate before calling
import os
if not os.access(conf_path, os.W_OK):
raise PermissionError(f"cannot write config {conf_path}; fix ownership/mount") Try / catch
try:
rewrite_yaml_conf("conf/service_conf.yaml", config)
except EnvironmentError as e:
log.error("config save failed: %s (cause: %s)", e, e.args[1] if len(e.args) > 1 else None)
# keep in-memory config, schedule retry or surface to operator Prevention
- Ensure the service user owns conf/ in container/host deployments.
- Avoid read-only mounts for directories the app writes config into.
- Keep config values plain YAML types (str/int/bool/dict/list) before dumping.
When it happens
Trigger: Code path that saves configuration (e.g. applying settings changes that call rewrite_yaml_conf) when the conf file or directory is not writable: container deployments running as non-root with root-owned conf files, read-only volumes, or a config payload containing Python objects ruamel.yaml's safe dumper cannot represent.
Common situations: Docker deployment where /ragflow/conf was mounted read-only or chowned to root; running the service as an unprivileged user after installing as root; SELinux/AppArmor denying writes; a config value that is a Python object (e.g. datetime with custom representer missing) rather than plain YAML types.
Related errors
- Failed to create remote workspace on {self.host}: {stderr or
- Invalid config file: "{local_path}".
- Invalid config file: "{global_config_path}".
- failed to initialize logger: {err}
- main() must return a value. Use null for an empty result.
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/20efe0cb9472aec2.
Report an issue: GitHub.