From 9d1bf9d139028198cb76f2cce7fac414177a79f3 Mon Sep 17 00:00:00 2001 From: Nick Rhodes Date: Wed, 8 Feb 2023 16:36:14 +0000 Subject: [PATCH 1/3] Create unique error message when state.find_name returns more than one match It's possible for `state.find_name()` to return more than one match for a state ID, e.g. when a user has their groups modified by multiple states (`remove_groups: false`). If a state then tried to reference that user via their name: ``` testfile: file.managed: [...] - require_in: - user: nobody ``` Multiple states could match the requisite. The PR updates the error message returned when this happens to explicitly state that there are multiple states for that ID, and hence it's not possible to create the requisite. --- salt/state.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/salt/state.py b/salt/state.py index 28d7fc06a5f8..7a607f481cb6 100644 --- a/salt/state.py +++ b/salt/state.py @@ -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" @@ -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] From 815fd012ee02b28a9a7cb9a24f1422c0b335801a Mon Sep 17 00:00:00 2001 From: "Daniel A. Wozniak" Date: Sat, 6 Jun 2026 15:04:34 -0700 Subject: [PATCH 2/3] Add regression test for duplicate-extend-id error message (#63673) --- .../modules/state/requisites/test_require.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/pytests/functional/modules/state/requisites/test_require.py b/tests/pytests/functional/modules/state/requisites/test_require.py index 9198b8496daa..1582799eea8d 100644 --- a/tests/pytests/functional/modules/state/requisites/test_require.py +++ b/tests/pytests/functional/modules/state/requisites/test_require.py @@ -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 From 5a63fdcde4eacbcf69965f459bf8e04e0fca8485 Mon Sep 17 00:00:00 2001 From: "Daniel A. Wozniak" Date: Sat, 6 Jun 2026 15:04:45 -0700 Subject: [PATCH 3/3] Add changelog fragment for #63673 --- changelog/63673.changed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/63673.changed.md diff --git a/changelog/63673.changed.md b/changelog/63673.changed.md new file mode 100644 index 000000000000..941c9cf0287b --- /dev/null +++ b/changelog/63673.changed.md @@ -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.