Skip to content

Commit dc09b64

Browse files
committed
Extend validation of finecode-user.toml
1 parent 10a8c3b commit dc09b64

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

src/finecode/wm_server/config/read_configs.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ def read_project_user_config(project_dir: Path) -> dict | None:
4040
Returns the parsed mapping, or None if the file does not exist.
4141
4242
Raises:
43-
ConfigurationError: File is malformed or contains a [workspace] table.
43+
ConfigurationError: File is malformed or contains a [workspace] or
44+
[tool] table.
4445
"""
4546
user_config_path = project_dir / "finecode-user.toml"
4647
if not user_config_path.exists():
@@ -58,6 +59,13 @@ def read_project_user_config(project_dir: Path) -> dict | None:
5859
f"{user_config_path}. "
5960
f"Workspace configuration must live in finecode-workspace.toml."
6061
)
62+
if "tool" in raw:
63+
raise config_models.ConfigurationError(
64+
f"The [tool] table is not allowed in {user_config_path}. "
65+
f"finecode-user.toml uses the same fields as finecode.toml but "
66+
f"without the [tool.finecode] wrapper — write tables directly, "
67+
f"e.g. [action.x] instead of [tool.finecode.action.x]."
68+
)
6169
return raw
6270

6371

@@ -563,6 +571,13 @@ def read_preset_config(
563571
raise config_models.ConfigurationError(
564572
f"The [workspace] table is not allowed in {preset_user_config_path}."
565573
)
574+
if "tool" in preset_user_raw:
575+
raise config_models.ConfigurationError(
576+
f"The [tool] table is not allowed in {preset_user_config_path}. "
577+
f"finecode-user.toml uses the same fields as preset.toml but "
578+
f"without the [tool.finecode] wrapper — write tables directly, "
579+
f"e.g. [action.x] instead of [tool.finecode.action.x]."
580+
)
566581
if "dependency-groups" in preset_user_raw:
567582
logger.warning(
568583
f"[dependency-groups] in {preset_user_config_path} is not supported "

tests/unit/test_read_configs.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ def test_project_user_config_workspace_table_raises(tmp_path: pathlib.Path) -> N
4444
read_project_user_config(tmp_path)
4545

4646

47+
def test_project_user_config_tool_table_raises(tmp_path: pathlib.Path) -> None:
48+
"""A [tool] table in finecode-user.toml is rejected with a clear error.
49+
50+
finecode-user.toml is unwrapped (no [tool.finecode] prefix); writing
51+
[tool.finecode.action.x] instead of [action.x] used to reach
52+
`_merge_projects_configs` and crash there with a bare `KeyError('tool')`
53+
surfaced to the client as `API error (-32603): 'tool'`. Reject it eagerly
54+
with an actionable message instead.
55+
"""
56+
_write_toml(
57+
tmp_path / "finecode-user.toml",
58+
"[tool.finecode.action.lint]\nhandlers = []\n",
59+
)
60+
with pytest.raises(config_models.ConfigurationError, match=r"\[tool\]"):
61+
read_project_user_config(tmp_path)
62+
63+
4764
def test_project_user_config_malformed_raises(tmp_path: pathlib.Path) -> None:
4865
"""A parse error in finecode-user.toml is a hard failure.
4966
@@ -846,3 +863,20 @@ def test_preset_user_config_workspace_table_raises(tmp_path: pathlib.Path) -> No
846863
_write_toml(tmp_path / "finecode-user.toml", "[workspace]\nfoo = 1\n")
847864
with pytest.raises(config_models.ConfigurationError, match="workspace"):
848865
read_preset_config(tmp_path / "preset.toml", "mypkg")
866+
867+
868+
def test_preset_user_config_tool_table_raises(tmp_path: pathlib.Path) -> None:
869+
"""A [tool] table in a preset-level finecode-user.toml is rejected.
870+
871+
Same double-wrapping bug as at the project level — a preset's
872+
finecode-user.toml is unwrapped, so [tool.finecode.action.x] used to
873+
reach `_merge_projects_configs` and crash with a bare `KeyError('tool')`
874+
instead of an actionable error.
875+
"""
876+
_write_minimal_preset(tmp_path)
877+
_write_toml(
878+
tmp_path / "finecode-user.toml",
879+
"[tool.finecode.action.lint]\nhandlers = []\n",
880+
)
881+
with pytest.raises(config_models.ConfigurationError, match=r"\[tool\]"):
882+
read_preset_config(tmp_path / "preset.toml", "mypkg")

0 commit comments

Comments
 (0)