Repository: pdm-project/pdm

Issue:
Inconsistent behavior between `pdm remove` and `pdm update`
## Is your feature/enhancement proposal related to a problem? Please describe.

I don't know if it's intentional or something that needs to be improved. When you delete a dev package, you will need to select the dependency group correctly:

```
$ pdm remove ruff
Removing packages from default dependencies: ruff
[ProjectError]: ruff does not exist in default dependencies.
```

You have to use `pdm remove --dev` or `pdm remove -dG` based on the specific group:

```
$ pdm remove --dev ruff
Removing packages from dev dev-dependencies: ruff
...
  ✔ Remove ruff 0.4.4 successful

🎉 All complete!
```

But the `pdm update` doesn't check the dependency group:

```
$ pdm update ruff
Updating packages: ruff.
🔒 Lock successful
All packages are synced to date, nothing to do.

🎉 All complete!
```

## Describe the solution you'd like

<!--A clear and concise description of what you ant to happen.-->

Make the behavior consistent between `pdm remove` and `pdm update` if possible.



Discussion:

Patch:
diff --git a/news/2885.bugfix.md b/news/2885.bugfix.md
new file mode 100644
index 0000000000..27ccb2b9fe
--- /dev/null
+++ b/news/2885.bugfix.md
@@ -0,0 +1,1 @@
+Raise an error if the package given by `pdm update` does not exist in the select dependency group but in other groups.
diff --git a/src/pdm/cli/commands/update.py b/src/pdm/cli/commands/update.py
index 1ccaeb05b9..c52a4fdb09 100644
--- a/src/pdm/cli/commands/update.py
+++ b/src/pdm/cli/commands/update.py
@@ -149,6 +149,14 @@ def do_update(
                             f"[req]{name}[/] does not exist in [primary]{group}[/] "
                             f"{'dev-' if selection.dev else ''}dependencies nor is a transitive dependency."
                         )
+                    look_in_other_group = next(
+                        (g for g, deps in all_dependencies.items() if normalized_name in deps and g != group), None
+                    )
+                    if look_in_other_group is not None:
+                        raise ProjectError(
+                            f"[req]{name}[/] does not exist in [primary]{group}[/], but exists in [primary]{look_in_other_group}[/]."
+                            " Please specify the correct group with `-G/--group`."
+                        )
                     tracked_names.add(normalized_name)
                 else:
                     matched_req.prerelease = prerelease


Test patch:
diff --git a/tests/cli/test_update.py b/tests/cli/test_update.py
index 1b111aa931..0a5dbfa586 100644
--- a/tests/cli/test_update.py
+++ b/tests/cli/test_update.py
@@ -184,13 +184,21 @@ def test_update_transitive(project, repository, pdm):
 
 
 @pytest.mark.usefixtures("working_set")
-def test_update_transitive_nonexistant_dependencies(project, repository, pdm):
+def test_update_transitive_nonexistant_dependencies(project, pdm):
     pdm(["add", "requests", "--no-sync"], obj=project, strict=True)
-    result = pdm(["update", "numpy"])
+    result = pdm(["update", "numpy"], obj=project)
     assert "ProjectError" in result.stderr
     assert "numpy does not exist in" in result.stderr
 
 
+@pytest.mark.usefixtures("working_set")
+def test_update_package_wrong_group(project, pdm):
+    pdm(["add", "-d", "requests"], obj=project, strict=True)
+    result = pdm(["update", "requests"], obj=project)
+    assert "ProjectError" in result.stderr
+    assert "requests does not exist in default, but exists in dev" in result.stderr
+
+
 @pytest.mark.usefixtures("working_set")
 def test_update_transitive_non_transitive_dependencies(project, repository, pdm):
     pdm(["add", "requests", "pytz", "--no-sync"], obj=project, strict=True)