Repository: conan-io/conan
Pull request #18153 (2025-04-21 11:49:46)

Raise an error if LocalRecipesIndex user/channel doesn't match requested one
Changelog: Bugfix: Raise a not-found error if "local recipes index" ``user/channel`` doesn't match requested one
Docs: Omit

Close https://github.com/conan-io/conan/issues/18142



Patch:
diff --git a/conans/client/rest_client_local_recipe_index.py b/conans/client/rest_client_local_recipe_index.py
index 3a4e65d1d..a5f896def 100644
--- a/conans/client/rest_client_local_recipe_index.py
+++ b/conans/client/rest_client_local_recipe_index.py
@@ -134,11 +134,6 @@ class RestApiClientLocalRecipesIndex:
 
     def get_recipe_revision_reference(self, ref):
         new_ref = self._export_recipe(ref)
-        if new_ref != ref:
-            ConanOutput().warning(f"A specific revision '{ref.repr_notime()}' was requested, but it "
-                                  "doesn't match the current available revision in source. The "
-                                  "local-recipes-index can't provide a specific revision")
-            raise RecipeNotFoundException(ref)
         return new_ref
 
     def get_package_revision_reference(self, pref):
@@ -162,6 +157,13 @@ class RestApiClientLocalRecipesIndex:
             sys.stderr = original_stderr
             ConanOutput(scope="local-recipes-index").debug(f"Internal export for {ref}:\n"
                                                            f"{textwrap.indent(export_err, '    ')}")
+        if new_ref.user != ref.user or new_ref.channel != ref.channel:
+            raise RecipeNotFoundException(ref)
+        if ref.revision is not None and new_ref.revision != ref.revision:
+            ConanOutput().warning(f"A specific revision '{ref.repr_notime()}' was requested, but it "
+                                  "doesn't match the current available revision in source. The "
+                                  "local-recipes-index can't provide a specific revision")
+            raise RecipeNotFoundException(ref)
         return new_ref
 
     @staticmethod


Test patch:
diff --git a/test/integration/remote/test_local_recipes_index.py b/test/integration/remote/test_local_recipes_index.py
index bbff7cebe..eee9bf18d 100644
--- a/test/integration/remote/test_local_recipes_index.py
+++ b/test/integration/remote/test_local_recipes_index.py
@@ -102,6 +102,13 @@ class TestSearchList:
         revs = listjson["local"]["zlib/1.2.11"]["revisions"]
         assert len(revs) == 1 and "6f5c31bb1219e9393743d1fbf2ee1b52" in revs
 
+    def test_list_revisions_notfound(self, c3i_folder):
+        client = TestClient(light=True)
+        client.run(f"remote add local '{c3i_folder}'")
+        client.run("list potato/1.0#* -r=local")
+        # More like remotes than cache
+        assert "ERROR: Recipe not found: 'potato/1.0'"
+
     def test_list_rrevs(self, c3i_folder):
         client = TestClient(light=True)
         client.run(f"remote add local '{c3i_folder}'")
@@ -349,6 +356,41 @@ class TestErrorsUx:
         c.run("install --requires=zlib/1.2.11#rev1", assert_error=True)
         assert "A specific revision 'zlib/1.2.11#rev1' was requested" in c.out
 
+    def test_no_user_channel(self):
+        # https://github.com/conan-io/conan/issues/18142
+        folder = temp_folder()
+        recipes_folder = os.path.join(folder, "recipes")
+        zlib_config = textwrap.dedent("""
+          versions:
+            "0.1":
+              folder: all
+          """)
+        zlib = GenConanfile("zlib")
+        conandata_yml = textwrap.dedent("""\
+          versions:
+            "0.1":
+          """)
+        save_files(recipes_folder, {"zlib/config.yml": zlib_config,
+                                    "zlib/all/conanfile.py": str(zlib),
+                                    "zlib/all/conandata.yml": conandata_yml})
+        c = TestClient()
+        c.run(f"remote add local '{folder}'")
+        c.run("install --requires=zlib/0.1@myuser/mychannel", assert_error=True)
+        assert "ERROR: Package 'zlib/0.1@myuser/mychannel' not resolved" in c.out
+
+        c = TestClient(default_server_user=True)
+        c.save({"conanfile.py": GenConanfile("zlib", "0.1")})
+        c.run("create . --user=myuser --channel=mychannel")
+        c.run("upload * -r=default -c")
+        c.run(f"remote add local '{folder}' --index=0")
+        c.run("install --requires=zlib/0.1@myuser/mychannel")
+        c.assert_listed_require({"zlib/0.1@myuser/mychannel": "Cache"})
+
+        # Force resolving in remotes
+        c.run("remove * -c")
+        c.run("install --requires=zlib/0.1@myuser/mychannel")
+        c.assert_listed_require({"zlib/0.1@myuser/mychannel": "Downloaded (default)"})
+
 
 class TestPythonRequires:
     @pytest.fixture(scope="class")