{"record":{"id":"20efe0cb9472aec2","repo":"infiniflow/ragflow","slug":"rewrite-yaml-file-config-failed","errorCode":null,"errorMessage":"rewrite yaml file config {} failed:","messagePattern":"rewrite yaml file config (.+?) failed:","errorType":"exception","errorClass":"EnvironmentError","httpStatus":null,"severity":"error","filePath":"common/config_utils.py","lineNumber":47,"sourceCode":"    if not os.path.isabs(conf_path):\n        conf_path = os.path.join(get_project_base_directory(), conf_path)\n    try:\n        with open(conf_path) as f:\n            yaml = YAML(typ=\"safe\", pure=True)\n            return yaml.load(f)\n    except Exception as e:\n        raise EnvironmentError(\"loading yaml file config from {} failed:\".format(conf_path), e)\n\n\ndef rewrite_yaml_conf(conf_path, config):\n    if not os.path.isabs(conf_path):\n        conf_path = os.path.join(get_project_base_directory(), conf_path)\n    try:\n        with open(conf_path, \"w\") as f:\n            yaml = YAML(typ=\"safe\")\n            yaml.dump(config, f)\n    except Exception as e:\n        raise EnvironmentError(\"rewrite yaml file config {} failed:\".format(conf_path), e)\n\n\ndef conf_realpath(conf_name):\n    conf_path = f\"conf/{conf_name}\"\n    return os.path.join(get_project_base_directory(), conf_path)\n\n\ndef read_config(conf_name=SERVICE_CONF):\n    local_config = {}\n    local_path = conf_realpath(f\"local.{conf_name}\")\n\n    # load local config file\n    if os.path.exists(local_path):\n        local_config = load_yaml_conf(local_path)\n        if not isinstance(local_config, dict):\n            raise ValueError(f'Invalid config file: \"{local_path}\".')\n\n    global_config_path = conf_realpath(conf_name)","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/config_utils.py#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: conf owned by root, service runs as ragflow user\n# after\nchown -R ragflow:ragflow /path/to/ragflow/conf\nchmod u+w /path/to/ragflow/conf/service_conf.yaml","handlingStrategy":"try-catch","validationCode":"import os\nif not os.access(conf_path, os.W_OK):\n    raise PermissionError(f\"cannot write config {conf_path}; fix ownership/mount\")","typeGuard":null,"tryCatchPattern":"try:\n    rewrite_yaml_conf(\"conf/service_conf.yaml\", config)\nexcept EnvironmentError as e:\n    log.error(\"config save failed: %s (cause: %s)\", e, e.args[1] if len(e.args) > 1 else None)\n    # keep in-memory config, schedule retry or surface to operator","preventionTips":["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."],"tags":["config","yaml","filesystem","permissions","deployment"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}