From 364c08c6e21c5a07e04da204e55cd2a89e903b74 Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Tue, 21 Apr 2026 13:51:17 +0200 Subject: [PATCH] Improve loading of `project.yml` files: Gracefully handle user errors involving incorrect use of None/empty instead of list Resolves #1390 --- CHANGELOG.md | 3 ++- src/serena/config/serena_config.py | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71e6f892..5b3453c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ Status of the `main` branch. Changes prior to the next official version change w - Security: Add check for tool being read-only in the project server (previously only checked in `query_project` tool, i.e. client side) - Usage reporting now also includes the name of the Serena context that is used - Fix: restricted `insert_after_symbol` to raise if used on an assignment or similar (can't reliably determine the symbol range) - - Fix: Failure to collect project ignore spec now logs the error and downstream tasks fail fast, fixing hanging LS initialisation + - Fix: Failure to collect project ignore spec now logs the error and downstream tasks fail fast, fixing hanging LS initialisation + - Improve loading of `project.yml` files: Gracefully handle user errors involving incorrect use of None/empty instead of list * JetBrains: - `Move` and `SafeDelete` tools: transform empty string to None (counteracts client errors) diff --git a/src/serena/config/serena_config.py b/src/serena/config/serena_config.py index 26815061..457e0705 100644 --- a/src/serena/config/serena_config.py +++ b/src/serena/config/serena_config.py @@ -418,6 +418,10 @@ class ProjectConfig(SharedConfig): data["languages"] = [data["language"]] del data["language"] + # Note: Checks for validity of fields must not happen here but in _from_dict. + # Here, the data may be incomplete, because this function is also used for + # loading project.local.yml files. + return data, was_complete @classmethod @@ -461,13 +465,19 @@ class ProjectConfig(SharedConfig): line_ending_value = data.get("line_ending") line_ending = LineEnding.from_str(line_ending_value) if line_ending_value else None + # gracefully handle user errors: incorrect use of None/empty where a list is required + ignored_paths = data["ignored_paths"] or [] + fixed_tools = data["fixed_tools"] or [] + excluded_tools = data["excluded_tools"] or [] + included_optional_tools = data["included_optional_tools"] or [] + return cls( project_name=data["project_name"], languages=languages, - ignored_paths=data["ignored_paths"], - excluded_tools=data["excluded_tools"], - fixed_tools=data["fixed_tools"], - included_optional_tools=data["included_optional_tools"], + ignored_paths=ignored_paths, + excluded_tools=excluded_tools, + fixed_tools=fixed_tools, + included_optional_tools=included_optional_tools, read_only=data["read_only"], read_only_memory_patterns=data.get("read_only_memory_patterns", []), ignored_memory_patterns=data.get("ignored_memory_patterns", []),