{"record":{"id":"305b94f6c70596b2","repo":"sgl-project/sglang","slug":"config-file-must-contain-a-dictionary-at-root-leve","errorCode":null,"errorMessage":"Config file must contain a dictionary at root level","messagePattern":"Config file must contain a dictionary at root level","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/utils/server_args_config_parser.py","lineNumber":128,"sourceCode":"\n        Raises:\n            ValueError: If file is not YAML or cannot be read\n        \"\"\"\n        self._validate_yaml_file(file_path)\n\n        try:\n            with open(file_path, \"r\") as file:\n                config_data = yaml.safe_load(file)\n        except Exception as e:\n            logger.error(f\"Failed to read config file {file_path}: {e}\")\n            raise\n\n        # Handle empty files or None content\n        if config_data is None:\n            config_data = {}\n\n        if not isinstance(config_data, dict):\n            raise ValueError(\"Config file must contain a dictionary at root level\")\n\n        return config_data\n\n    def _validate_yaml_file(self, file_path: str) -> None:\n        \"\"\"Validate that the file is a YAML file.\"\"\"\n        path = Path(file_path)\n        if path.suffix.lower() not in [\".yaml\", \".yml\"]:\n            raise ValueError(f\"Config file must be YAML format, got: {path.suffix}\")\n\n        if not path.exists():\n            raise ValueError(f\"Config file not found: {file_path}\")\n\n    def _convert_config_to_args(self, config: Dict[str, Any]) -> List[str]:\n        \"\"\"Convert configuration dictionary to argument list.\"\"\"\n        args = []\n\n        for key, value in config.items():\n            key_norm = key.replace(\"-\", \"_\")","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/utils/server_args_config_parser.py#L110-L146","documentation":"YAML configs must be a mapping of option-name to value at the root. After yaml.safe_load, empty/None files become {}, but any other non-dict root (list, scalar, plain string) raises this error.","triggerScenarios":"A YAML file whose root node is a sequence (- model-path: x) or a bare scalar/string instead of key: value mappings.","commonSituations":"Hand-written config that indents all keys under a list dash, a JSON-style array file renamed to .yaml, or copy-pasting an example that used a list of configs.","solutions":["Make the root a mapping: top-level `key: value` lines with no leading dash","Wrap the list under a named key if the list was intentional","Validate with `python -c \"import yaml;print(type(yaml.safe_load(open('cfg.yaml'))))` expecting dict"],"exampleFix":"# before\n- model-path: meta-llama/Llama-3-8B\n- port: 8000\n# after\nmodel-path: meta-llama/Llama-3-8B\nport: 8000","handlingStrategy":"validation","validationCode":"import yaml\ndata = yaml.safe_load(open(\"config.yaml\"))\nassert isinstance(data, dict) or data is None, \"config root must be a mapping\"","typeGuard":"def is_valid_config(data) -> bool:\n    return data is None or isinstance(data, dict)","tryCatchPattern":null,"preventionTips":["Lint YAML configs in CI with a root-type check","Keep an example config that developers copy from"],"tags":["sglang","yaml","config","validation"],"backgroundTag":"yaml-schema-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}