flake: prevent outPath in multiselect to avoid serialization issues

When using multiselect with outPath like {outPath,?meta}, nix evaluation
collapses the attrset to just the outPath string, breaking further selection.
Add validation during selector parsing to catch this and provide a clear error.
This commit is contained in:
lassulus
2025-07-02 16:50:21 +02:00
parent d5a1aba480
commit 30bc8cb5d3
2 changed files with 24 additions and 0 deletions

View File

@@ -168,6 +168,16 @@ def parse_selector(selector: str) -> list[Selector]:
else:
set_select_type = SetSelectorType.STR
acc_selectors.append(SetSelector(type=set_select_type, value=acc_str))
# Check for invalid multiselect patterns with outPath
for subselector in acc_selectors:
if subselector.value == "outPath":
msg = (
"Cannot use 'outPath' in multiselect {...}. "
"When nix evaluates attrsets with outPath in a multiselect, "
"it collapses the entire attrset to just the outPath string, "
"breaking further selection. Use individual selectors instead."
)
raise ValueError(msg)
selectors.append(Selector(type=SelectorType.SET, value=acc_selectors))
submode = ""

View File

@@ -168,6 +168,20 @@ def test_out_path() -> None:
assert test_cache.select(selectors) == "/nix/store/bla"
def test_out_path_in_multiselect_raises_exception() -> None:
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
parse_selector("{outPath}")
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
parse_selector("x.{y,outPath}")
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
parse_selector("a.b.{c,d,outPath,e}")
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
parse_selector("{?outPath}")
@pytest.mark.with_core
def test_conditional_all_selector(flake: ClanFlake) -> None:
m1 = flake.machines["machine1"]