{"record":{"id":"1fc8ef8071734038","repo":"oraios/serena","slug":"projects-key-not-found-in-serena-configuration","errorCode":null,"errorMessage":"`projects` key not found in Serena configuration. Please update your `serena_config.yml` file.","messagePattern":"`projects` key not found in Serena configuration\\. Please update your `serena_config\\.yml` file\\.","errorType":"exception","errorClass":"SerenaConfigError","httpStatus":null,"severity":"error","filePath":"src/serena/config/serena_config.py","lineNumber":1064,"sourceCode":"\n        # create the configuration instance\n        instance = cls(_loaded_commented_yaml=loaded_commented_yaml, _config_file_path=config_file_path)\n        num_migrations = 0\n\n        def get_value_or_default(field_name: str) -> Any:\n            nonlocal num_migrations\n            if field_name not in loaded_commented_yaml:\n                num_migrations += 1\n            return loaded_commented_yaml.get(field_name, get_dataclass_default(SerenaConfig, field_name))\n\n        # transfer regular fields that do not require type conversion\n        for field_name in instance._iter_config_file_mapped_fields_without_type_conversion():\n            assert hasattr(instance, field_name)\n            setattr(instance, field_name, get_value_or_default(field_name))\n\n        # read projects\n        if \"projects\" not in loaded_commented_yaml:\n            raise SerenaConfigError(\"`projects` key not found in Serena configuration. Please update your `serena_config.yml` file.\")\n        instance.projects = []\n        for path in loaded_commented_yaml[\"projects\"] or []:\n            path = Path(path).resolve()\n            try:\n                path_exists = path.exists()\n            except OSError as e:\n                log.warning(f\"Project path {path} is not accessible ({e}), skipping.\")\n                continue\n            if not path_exists or (path.is_dir() and not os.path.isfile(instance.get_project_yml_location(str(path)))):\n                log.warning(f\"Project path {path} does not exist or no associated project configuration file found, skipping.\")\n                continue\n            if path.is_file():\n                path = cls._migrate_out_of_project_config_file(path)\n                if path is None:\n                    continue\n                num_migrations += 1\n            try:\n                project_config = ProjectConfig.load(path, serena_config=instance)  # instance is sufficiently populated","sourceCodeStart":1046,"sourceCodeEnd":1082,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/config/serena_config.py#L1046-L1082","documentation":"After parsing serena_config.yml, from_config_file() requires the top-level `projects` key listing registered project paths. Older or hand-trimmed config files lacking this key are rejected with SerenaConfigError, telling the user to update their config to the new schema.","triggerScenarios":"Loading a serena_config.yml (generated by an older Serena version or edited to remove the key) that has no `projects` mapping/sequence; from_config_file then raises during startup of make_agent, main, edit, etc.","commonSituations":"Upgrading Serena from a version whose config template had no `projects` key; copying only partial settings into a fresh config; manually pruning the file and deleting the empty-looking `projects:` section.","solutions":["Add a `projects:` key to serena_config.yml (an empty list `projects: []` is valid) and re-run.","Regenerate the config from the current template (delete the old file and let from_config_file(generate_if_missing=True) recreate it), then re-add your settings.","If migrating, run Serena's config migration path (from_config_file performs migrations) rather than hand-building the file."],"exampleFix":"// before (serena_config.yml)\ngui_launch_window: 0\n// after\nprojects: []\ngui_launch_window: 0","handlingStrategy":"fallback","validationCode":"import yaml\ndata = yaml.safe_load(open(config_path))\nif 'projects' not in data:\n    data['projects'] = []  # or rewrite the file with the key added","typeGuard":"def has_projects_key(path) -> bool:\n    import yaml\n    return 'projects' in (yaml.safe_load(open(path)) or {})","tryCatchPattern":"try:\n    config = SerenaConfig.from_config_file()\nexcept SerenaConfigError as e:\n    if 'projects' in str(e):\n        add_projects_key_to_yml(); config = SerenaConfig.from_config_file()\n    else:\n        raise","preventionTips":["Regenerate serena_config.yml from the template when upgrading Serena versions","Never delete top-level keys, even empty ones, when hand-editing","Diff your config against the shipped template after upgrades"],"tags":["configuration","schema","migration","python"],"backgroundTag":"config-schema-mismatch","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}