Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/63673.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved the "Cannot extend ID" compiler error to identify the duplicate state IDs when an extend or require_in target matches more than one state's ``name`` parameter, instead of returning the generic "not part of the high state" message.
18 changes: 17 additions & 1 deletion salt/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,7 @@ def reconcile_extend(self, high: HighData, strict=False):
if name not in high or state_type not in high[name]:
# Check for a matching 'name' override in high data
ids = find_name(name, state_type, high, strict=strict)
if len(ids) != 1:
if len(ids) == 0:
errors.append(
"Cannot extend ID '{0}' in '{1}:{2}'. It is not "
"part of the high state.\n"
Expand All @@ -1813,6 +1813,22 @@ def reconcile_extend(self, high: HighData, strict=False):
)
)
continue
elif len(ids) > 1:
errors.append(
"Cannot extend ID '{0}' in '{1}:{2}'. It is not "
"unique in the running high state.\n"
"This is likely due to more than one state using "
"the same `name` parameter. Ensure that\nthe "
"state with an ID of '{0}' is unique in "
"environment '{1}' and to SLS '{2}'.\nDuplicate "
"states IDs are: '{3}'".format(
name,
body.get("__env__", "base"),
body.get("__sls__", "base"),
", ".join(f"{state}: {id}" for id, state in ids),
)
)
continue
else:
name = ids[0][0]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,44 @@ def test_requisites_require_ordering_and_errors_5(state, state_tree):
assert ret.errors == [errmsg]


def test_requisites_require_ordering_duplicate_extend_id(state, state_tree):
"""
Regression test for PR #63673.

When the target of an extend (or a require_in, which desugars to extend)
cannot be resolved to a single state because multiple states share the
same ``name`` parameter, the compiler should fail with a "not unique"
error that names every duplicate, instead of the older generic
"not part of the high state" message.
"""
sls_contents = """
state_a:
test.succeed_without_changes:
- name: duplicate-target

state_b:
test.succeed_without_changes:
- name: duplicate-target

trigger:
test.succeed_without_changes:
- require_in:
- test: duplicate-target
"""
errmsg = (
"Cannot extend ID 'duplicate-target' in 'base:requisite'. It is not"
" unique in the running high state.\nThis is likely due to more than"
" one state using the same `name` parameter. Ensure that\nthe state"
" with an ID of 'duplicate-target' is unique in environment 'base'"
" and to SLS 'requisite'.\nDuplicate states IDs are:"
" 'test: state_a, test: state_b'"
)
with pytest.helpers.temp_file("requisite.sls", sls_contents, state_tree):
ret = state.sls("requisite")
assert ret.failed
assert ret.errors == [errmsg]


def test_requisites_require_with_order_first_last(state, state_tree):
"""
Call sls file containing a state with require_in order first
Expand Down
Loading