We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[api] Confusing error when trying to sync project set to scm_type Manual
### Please confirm the following

- [X] I agree to follow this project's [code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).
- [X] I have checked the [current issues](https://github.com/ansible/awx/issues) for duplicates.
- [X] I understand that AWX is open source software provided for free and that I might not receive a timely response.

### Bug Summary

Creating a project and accidentally setting it to be `scm_type: manual` (the default in the awx collection), and then trying to do a project update on it, leads to a very confusing error:

```
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Cannot make a request with the POST method to this endpoint /api/v2/projects/8/update/"}
```

Although it is "technically" correct, it would be nice if we could show something nicer in this scenario (e.g. "Unable to trigger a project update because the project scm type (Manual) does not support it.")

### AWX version

devel

### Select the relevant components

- [ ] UI
- [X] API
- [ ] Docs
- [ ] Collection
- [ ] CLI
- [ ] Other

### Installation method

docker development environment

### Modifications

no

### Ansible version

_No response_

### Operating system

_No response_

### Web browser

_No response_

### Steps to reproduce

- Create a project, set its type to Manual
- Use the API (or `awx.awx.project_update`) to try to update it

### Expected results

An error explaining the problem

### Actual results

An error telling me that I can't POST to an endpoint that I expect to be able to POST to.

### Additional information

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `awx_collection/plugins/modules/project_update.py`
Content:
```
1 #!/usr/bin/python
2 # coding: utf-8 -*-
3 
4 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5 
6 from __future__ import absolute_import, division, print_function
7 
8 __metaclass__ = type
9 
10 ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], 'supported_by': 'community'}
11 
12 DOCUMENTATION = '''
13 ---
14 module: project_update
15 author: "Sean Sullivan (@sean-m-sullivan)"
16 short_description: Update a Project in Automation Platform Controller
17 description:
18     - Update a Automation Platform Controller Project. See
19       U(https://www.ansible.com/tower) for an overview.
20 options:
21     name:
22       description:
23         - The name or id of the project to update.
24       required: True
25       type: str
26       aliases:
27         - project
28     organization:
29       description:
30         - Organization the project exists in.
31         - Used to help lookup the object, cannot be modified using this module.
32         - If not provided, will lookup by name only, which does not work with duplicates.
33       type: str
34     wait:
35       description:
36         - Wait for the project to update.
37         - If scm revision has not changed module will return not changed.
38       default: True
39       type: bool
40     interval:
41       description:
42         - The interval to request an update from the controller.
43       required: False
44       default: 2
45       type: float
46     timeout:
47       description:
48         - If waiting for the project to update this will abort after this
49           amount of seconds
50       type: int
51 extends_documentation_fragment: awx.awx.auth
52 '''
53 
54 RETURN = '''
55 id:
56     description: project id of the updated project
57     returned: success
58     type: int
59     sample: 86
60 status:
61     description: status of the updated project
62     returned: success
63     type: str
64     sample: pending
65 '''
66 
67 
68 EXAMPLES = '''
69 - name: Launch a project with a timeout of 10 seconds
70   project_update:
71     project: "Networking Project"
72     timeout: 10
73 
74 - name: Launch a Project with extra_vars without waiting
75   project_update:
76     project: "Networking Project"
77     wait: False
78 '''
79 
80 from ..module_utils.controller_api import ControllerAPIModule
81 
82 
83 def main():
84     # Any additional arguments that are not fields of the item can be added here
85     argument_spec = dict(
86         name=dict(required=True, aliases=['project']),
87         organization=dict(),
88         wait=dict(default=True, type='bool'),
89         interval=dict(default=2.0, type='float'),
90         timeout=dict(default=None, type='int'),
91     )
92 
93     # Create a module for ourselves
94     module = ControllerAPIModule(argument_spec=argument_spec)
95 
96     # Extract our parameters
97     name = module.params.get('name')
98     organization = module.params.get('organization')
99     wait = module.params.get('wait')
100     interval = module.params.get('interval')
101     timeout = module.params.get('timeout')
102 
103     # Attempt to look up project based on the provided name or id
104     lookup_data = {}
105     if organization:
106         lookup_data['organization'] = module.resolve_name_to_id('organizations', organization)
107     project = module.get_one('projects', name_or_id=name, data=lookup_data)
108     if project is None:
109         module.fail_json(msg="Unable to find project")
110 
111     if wait:
112         scm_revision_original = project['scm_revision']
113 
114     # Update the project
115     result = module.post_endpoint(project['related']['update'])
116 
117     if result['status_code'] != 202:
118         module.fail_json(msg="Failed to update project, see response for details", response=result)
119 
120     module.json_output['changed'] = True
121     module.json_output['id'] = result['json']['id']
122     module.json_output['status'] = result['json']['status']
123 
124     if not wait:
125         module.exit_json(**module.json_output)
126 
127     # Invoke wait function
128     result = module.wait_on_url(
129         url=result['json']['url'], object_name=module.get_item_name(project), object_type='Project Update', timeout=timeout, interval=interval
130     )
131     scm_revision_new = result['json']['scm_revision']
132     if scm_revision_new == scm_revision_original:
133         module.json_output['changed'] = False
134 
135     module.exit_json(**module.json_output)
136 
137 
138 if __name__ == '__main__':
139     main()
140
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/awx_collection/plugins/modules/project_update.py b/awx_collection/plugins/modules/project_update.py
--- a/awx_collection/plugins/modules/project_update.py
+++ b/awx_collection/plugins/modules/project_update.py
@@ -114,7 +114,12 @@
     # Update the project
     result = module.post_endpoint(project['related']['update'])
 
-    if result['status_code'] != 202:
+    if result['status_code'] == 405:
+        module.fail_json(
+            msg="Unable to trigger a project update because the project scm_type ({0}) does not support it.".format(project['scm_type']),
+            response=result
+        )
+    elif result['status_code'] != 202:
         module.fail_json(msg="Failed to update project, see response for details", response=result)
 
     module.json_output['changed'] = True

{"golden_diff": "diff --git a/awx_collection/plugins/modules/project_update.py b/awx_collection/plugins/modules/project_update.py\n--- a/awx_collection/plugins/modules/project_update.py\n+++ b/awx_collection/plugins/modules/project_update.py\n@@ -114,7 +114,12 @@\n     # Update the project\n     result = module.post_endpoint(project['related']['update'])\n \n-    if result['status_code'] != 202:\n+    if result['status_code'] == 405:\n+        module.fail_json(\n+            msg=\"Unable to trigger a project update because the project scm_type ({0}) does not support it.\".format(project['scm_type']),\n+            response=result\n+        )\n+    elif result['status_code'] != 202:\n         module.fail_json(msg=\"Failed to update project, see response for details\", response=result)\n \n     module.json_output['changed'] = True\n", "issue": "[api] Confusing error when trying to sync project set to scm_type Manual\n### Please confirm the following\n\n- [X] I agree to follow this project's [code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html).\n- [X] I have checked the [current issues](https://github.com/ansible/awx/issues) for duplicates.\n- [X] I understand that AWX is open source software provided for free and that I might not receive a timely response.\n\n### Bug Summary\n\nCreating a project and accidentally setting it to be `scm_type: manual` (the default in the awx collection), and then trying to do a project update on it, leads to a very confusing error:\r\n\r\n```\r\nfatal: [localhost]: FAILED! => {\"changed\": false, \"msg\": \"Cannot make a request with the POST method to this endpoint /api/v2/projects/8/update/\"}\r\n```\r\n\r\nAlthough it is \"technically\" correct, it would be nice if we could show something nicer in this scenario (e.g. \"Unable to trigger a project update because the project scm type (Manual) does not support it.\")\n\n### AWX version\n\ndevel\n\n### Select the relevant components\n\n- [ ] UI\n- [X] API\n- [ ] Docs\n- [ ] Collection\n- [ ] CLI\n- [ ] Other\n\n### Installation method\n\ndocker development environment\n\n### Modifications\n\nno\n\n### Ansible version\n\n_No response_\n\n### Operating system\n\n_No response_\n\n### Web browser\n\n_No response_\n\n### Steps to reproduce\n\n- Create a project, set its type to Manual\r\n- Use the API (or `awx.awx.project_update`) to try to update it\n\n### Expected results\n\nAn error explaining the problem\n\n### Actual results\n\nAn error telling me that I can't POST to an endpoint that I expect to be able to POST to.\n\n### Additional information\n\n_No response_\n", "before_files": [{"content": "#!/usr/bin/python\n# coding: utf-8 -*-\n\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n\n__metaclass__ = type\n\nANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], 'supported_by': 'community'}\n\nDOCUMENTATION = '''\n---\nmodule: project_update\nauthor: \"Sean Sullivan (@sean-m-sullivan)\"\nshort_description: Update a Project in Automation Platform Controller\ndescription:\n    - Update a Automation Platform Controller Project. See\n      U(https://www.ansible.com/tower) for an overview.\noptions:\n    name:\n      description:\n        - The name or id of the project to update.\n      required: True\n      type: str\n      aliases:\n        - project\n    organization:\n      description:\n        - Organization the project exists in.\n        - Used to help lookup the object, cannot be modified using this module.\n        - If not provided, will lookup by name only, which does not work with duplicates.\n      type: str\n    wait:\n      description:\n        - Wait for the project to update.\n        - If scm revision has not changed module will return not changed.\n      default: True\n      type: bool\n    interval:\n      description:\n        - The interval to request an update from the controller.\n      required: False\n      default: 2\n      type: float\n    timeout:\n      description:\n        - If waiting for the project to update this will abort after this\n          amount of seconds\n      type: int\nextends_documentation_fragment: awx.awx.auth\n'''\n\nRETURN = '''\nid:\n    description: project id of the updated project\n    returned: success\n    type: int\n    sample: 86\nstatus:\n    description: status of the updated project\n    returned: success\n    type: str\n    sample: pending\n'''\n\n\nEXAMPLES = '''\n- name: Launch a project with a timeout of 10 seconds\n  project_update:\n    project: \"Networking Project\"\n    timeout: 10\n\n- name: Launch a Project with extra_vars without waiting\n  project_update:\n    project: \"Networking Project\"\n    wait: False\n'''\n\nfrom ..module_utils.controller_api import ControllerAPIModule\n\n\ndef main():\n    # Any additional arguments that are not fields of the item can be added here\n    argument_spec = dict(\n        name=dict(required=True, aliases=['project']),\n        organization=dict(),\n        wait=dict(default=True, type='bool'),\n        interval=dict(default=2.0, type='float'),\n        timeout=dict(default=None, type='int'),\n    )\n\n    # Create a module for ourselves\n    module = ControllerAPIModule(argument_spec=argument_spec)\n\n    # Extract our parameters\n    name = module.params.get('name')\n    organization = module.params.get('organization')\n    wait = module.params.get('wait')\n    interval = module.params.get('interval')\n    timeout = module.params.get('timeout')\n\n    # Attempt to look up project based on the provided name or id\n    lookup_data = {}\n    if organization:\n        lookup_data['organization'] = module.resolve_name_to_id('organizations', organization)\n    project = module.get_one('projects', name_or_id=name, data=lookup_data)\n    if project is None:\n        module.fail_json(msg=\"Unable to find project\")\n\n    if wait:\n        scm_revision_original = project['scm_revision']\n\n    # Update the project\n    result = module.post_endpoint(project['related']['update'])\n\n    if result['status_code'] != 202:\n        module.fail_json(msg=\"Failed to update project, see response for details\", response=result)\n\n    module.json_output['changed'] = True\n    module.json_output['id'] = result['json']['id']\n    module.json_output['status'] = result['json']['status']\n\n    if not wait:\n        module.exit_json(**module.json_output)\n\n    # Invoke wait function\n    result = module.wait_on_url(\n        url=result['json']['url'], object_name=module.get_item_name(project), object_type='Project Update', timeout=timeout, interval=interval\n    )\n    scm_revision_new = result['json']['scm_revision']\n    if scm_revision_new == scm_revision_original:\n        module.json_output['changed'] = False\n\n    module.exit_json(**module.json_output)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "awx_collection/plugins/modules/project_update.py"}], "after_files": [{"content": "#!/usr/bin/python\n# coding: utf-8 -*-\n\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n\n__metaclass__ = type\n\nANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], 'supported_by': 'community'}\n\nDOCUMENTATION = '''\n---\nmodule: project_update\nauthor: \"Sean Sullivan (@sean-m-sullivan)\"\nshort_description: Update a Project in Automation Platform Controller\ndescription:\n    - Update a Automation Platform Controller Project. See\n      U(https://www.ansible.com/tower) for an overview.\noptions:\n    name:\n      description:\n        - The name or id of the project to update.\n      required: True\n      type: str\n      aliases:\n        - project\n    organization:\n      description:\n        - Organization the project exists in.\n        - Used to help lookup the object, cannot be modified using this module.\n        - If not provided, will lookup by name only, which does not work with duplicates.\n      type: str\n    wait:\n      description:\n        - Wait for the project to update.\n        - If scm revision has not changed module will return not changed.\n      default: True\n      type: bool\n    interval:\n      description:\n        - The interval to request an update from the controller.\n      required: False\n      default: 2\n      type: float\n    timeout:\n      description:\n        - If waiting for the project to update this will abort after this\n          amount of seconds\n      type: int\nextends_documentation_fragment: awx.awx.auth\n'''\n\nRETURN = '''\nid:\n    description: project id of the updated project\n    returned: success\n    type: int\n    sample: 86\nstatus:\n    description: status of the updated project\n    returned: success\n    type: str\n    sample: pending\n'''\n\n\nEXAMPLES = '''\n- name: Launch a project with a timeout of 10 seconds\n  project_update:\n    project: \"Networking Project\"\n    timeout: 10\n\n- name: Launch a Project with extra_vars without waiting\n  project_update:\n    project: \"Networking Project\"\n    wait: False\n'''\n\nfrom ..module_utils.controller_api import ControllerAPIModule\n\n\ndef main():\n    # Any additional arguments that are not fields of the item can be added here\n    argument_spec = dict(\n        name=dict(required=True, aliases=['project']),\n        organization=dict(),\n        wait=dict(default=True, type='bool'),\n        interval=dict(default=2.0, type='float'),\n        timeout=dict(default=None, type='int'),\n    )\n\n    # Create a module for ourselves\n    module = ControllerAPIModule(argument_spec=argument_spec)\n\n    # Extract our parameters\n    name = module.params.get('name')\n    organization = module.params.get('organization')\n    wait = module.params.get('wait')\n    interval = module.params.get('interval')\n    timeout = module.params.get('timeout')\n\n    # Attempt to look up project based on the provided name or id\n    lookup_data = {}\n    if organization:\n        lookup_data['organization'] = module.resolve_name_to_id('organizations', organization)\n    project = module.get_one('projects', name_or_id=name, data=lookup_data)\n    if project is None:\n        module.fail_json(msg=\"Unable to find project\")\n\n    if wait:\n        scm_revision_original = project['scm_revision']\n\n    # Update the project\n    result = module.post_endpoint(project['related']['update'])\n\n    if result['status_code'] == 405:\n        module.fail_json(\n            msg=\"Unable to trigger a project update because the project scm_type ({0}) does not support it.\".format(project['scm_type']),\n            response=result\n        )\n    elif result['status_code'] != 202:\n        module.fail_json(msg=\"Failed to update project, see response for details\", response=result)\n\n    module.json_output['changed'] = True\n    module.json_output['id'] = result['json']['id']\n    module.json_output['status'] = result['json']['status']\n\n    if not wait:\n        module.exit_json(**module.json_output)\n\n    # Invoke wait function\n    result = module.wait_on_url(\n        url=result['json']['url'], object_name=module.get_item_name(project), object_type='Project Update', timeout=timeout, interval=interval\n    )\n    scm_revision_new = result['json']['scm_revision']\n    if scm_revision_new == scm_revision_original:\n        module.json_output['changed'] = False\n\n    module.exit_json(**module.json_output)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "awx_collection/plugins/modules/project_update.py"}]}