We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
GitLab SAST encounters error parsing the report
**Describe the issue**
`gitlab_sast` was added to the output in #4315. GitLab SAST produced the following error when attempting to parse the report.

```
[Schema] property '/vulnerabilities/0/identifiers/0/url' is not of type: string
[Schema] property '/vulnerabilities/0/links/0/url' is not of type: string
```

I found that `url` value is set to `null` which is not supported e.g.

```json
    "vulnerabilities": [
        {
            "id": "..."
            "identifiers": [
                {
                    "name": "CKV_AWS_283",
                    "type": "checkov",
                    "url": null,
                    "value": "CKV_AWS_283"
                }
            ],
            "links": [
                {
                    "url": null
                }
            ],
           ...
  ]
```

`url` is not a required field so instead of setting the value to `null`, drop the key altogether

schema reference: https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `checkov/common/output/gitlab_sast.py`
Content:
```
1 from __future__ import annotations
2 
3 from datetime import datetime
4 from typing import TYPE_CHECKING, Any
5 from uuid import uuid4
6 
7 from checkov.common.output.cyclonedx_consts import SCA_CHECKTYPES
8 from checkov.version import version
9 
10 if TYPE_CHECKING:
11     from checkov.common.output.record import Record
12     from checkov.common.output.report import Report
13 
14 DEFAULT_SEVERITY_GITLAB_LEVEL = "Unknown"
15 SEVERITY_TO_GITLAB_LEVEL = {
16     "critical": "Critical",
17     "high": "High",
18     "medium": "Medium",
19     "low": "Low",
20     "none": "Info",
21 }
22 
23 
24 class GitLabSast:
25     def __init__(self, reports: list[Report]):
26         self.reports = reports
27 
28         self.sast_json = self.create_sast_json()
29 
30     def create_sast_json(self) -> dict[str, Any]:
31         return {
32             "schema": "https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/v15.0.4/dist/sast-report-format.json",
33             "version": "15.0.4",
34             "scan": self._create_scan(),
35             "vulnerabilities": self._create_vulnerabilities(),
36         }
37 
38     def _create_scan(self) -> dict[str, Any]:
39         current_datetime = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")
40         scanner = {
41             "id": "checkov",
42             "name": "Checkov",
43             "url": "https://www.checkov.io/",
44             "vendor": {
45                 "name": "Bridgecrew",
46             },
47             "version": version,
48         }
49 
50         return {
51             "start_time": current_datetime,  # needs to be done properly in a later stage
52             "end_time": current_datetime,
53             "analyzer": scanner,  # same for us
54             "scanner": scanner,
55             "status": "success",
56             "type": "sast",
57         }
58 
59     def _create_vulnerabilities(self) -> list[dict[str, Any]]:
60         vulnerabilities = []
61 
62         for report in self.reports:
63             if report.check_type in SCA_CHECKTYPES:
64                 for check in report.failed_checks:
65                     vulnerability = None
66                     if check.check_id.startswith("BC_LIC"):
67                         vulnerability = self._create_license_vulnerability(record=check)
68                     elif check.check_id.startswith(("BC_VUL", "CKV_CVE")):
69                         vulnerability = self._create_cve_vulnerability(record=check)
70 
71                     if vulnerability:
72                         vulnerabilities.append(vulnerability)
73             else:
74                 for check in report.failed_checks:
75                     vulnerabilities.append(self._create_iac_vulnerability(record=check))
76 
77         return vulnerabilities
78 
79     def _create_iac_vulnerability(self, record: Record) -> dict[str, Any]:
80         severity = record.severity.name.lower() if record.severity else ""
81 
82         return {
83             "id": str(uuid4()),
84             "identifiers": [
85                 {
86                     "name": record.check_id,
87                     "type": "checkov",
88                     "url": record.guideline,
89                     "value": record.check_id,
90                 }
91             ],
92             "links": [
93                 {
94                     "url": record.guideline,
95                 }
96             ],
97             "location": {
98                 "file": record.repo_file_path.lstrip("/"),
99                 "start_line": record.file_line_range[0],
100                 "end_line": record.file_line_range[1],
101             },
102             "name": record.check_name,
103             "description": f"Further info can be found {record.guideline}",
104             "severity": SEVERITY_TO_GITLAB_LEVEL.get(severity, DEFAULT_SEVERITY_GITLAB_LEVEL),
105             "solution": f"Further info can be found {record.guideline}",
106         }
107 
108     def _create_cve_vulnerability(self, record: Record) -> dict[str, Any] | None:
109         details = record.vulnerability_details
110         if not details:
111             # this shouldn't happen
112             return None
113 
114         severity = record.severity.name.lower() if record.severity else ""
115 
116         return {
117             "id": str(uuid4()),
118             "identifiers": [
119                 {
120                     "name": record.short_description,
121                     "type": "cve",
122                     "url": details.get("link"),
123                     "value": details["id"],
124                 }
125             ],
126             "links": [
127                 {
128                     "url": details.get("link"),
129                 }
130             ],
131             "location": {
132                 "file": record.repo_file_path.lstrip("/"),
133             },
134             "name": record.short_description,
135             "description": details.get("description"),
136             "severity": SEVERITY_TO_GITLAB_LEVEL.get(severity, DEFAULT_SEVERITY_GITLAB_LEVEL),
137             "solution": details.get("status"),
138         }
139 
140     def _create_license_vulnerability(self, record: Record) -> dict[str, Any] | None:
141         details = record.vulnerability_details
142         if not details:
143             # this shouldn't happen
144             return None
145 
146         return {
147             "id": str(uuid4()),
148             "identifiers": [
149                 {
150                     "name": record.check_id,
151                     "type": "license",
152                     "value": record.check_id,
153                 }
154             ],
155             "location": {
156                 "file": record.repo_file_path.lstrip("/"),
157             },
158             "name": record.short_description,
159             "description": f"Package {details['package_name']}@{details['package_version']} has license {details['license']}",
160         }
161
```
--- 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/checkov/common/output/gitlab_sast.py b/checkov/common/output/gitlab_sast.py
--- a/checkov/common/output/gitlab_sast.py
+++ b/checkov/common/output/gitlab_sast.py
@@ -79,21 +79,15 @@
     def _create_iac_vulnerability(self, record: Record) -> dict[str, Any]:
         severity = record.severity.name.lower() if record.severity else ""
 
-        return {
+        vulnerability: "dict[str, Any]" = {
             "id": str(uuid4()),
             "identifiers": [
                 {
                     "name": record.check_id,
                     "type": "checkov",
-                    "url": record.guideline,
                     "value": record.check_id,
                 }
             ],
-            "links": [
-                {
-                    "url": record.guideline,
-                }
-            ],
             "location": {
                 "file": record.repo_file_path.lstrip("/"),
                 "start_line": record.file_line_range[0],
@@ -105,6 +99,17 @@
             "solution": f"Further info can be found {record.guideline}",
         }
 
+        if record.guideline:
+            # url can't be None
+            vulnerability["identifiers"][0]["url"] = record.guideline
+            vulnerability["links"] = [
+                {
+                    "url": record.guideline,
+                }
+            ]
+
+        return vulnerability
+
     def _create_cve_vulnerability(self, record: Record) -> dict[str, Any] | None:
         details = record.vulnerability_details
         if not details:
@@ -113,21 +118,15 @@
 
         severity = record.severity.name.lower() if record.severity else ""
 
-        return {
+        vulnerability: "dict[str, Any]" = {
             "id": str(uuid4()),
             "identifiers": [
                 {
                     "name": record.short_description,
                     "type": "cve",
-                    "url": details.get("link"),
                     "value": details["id"],
                 }
             ],
-            "links": [
-                {
-                    "url": details.get("link"),
-                }
-            ],
             "location": {
                 "file": record.repo_file_path.lstrip("/"),
             },
@@ -137,6 +136,18 @@
             "solution": details.get("status"),
         }
 
+        link = details.get("link")
+        if link:
+            # url can't be None
+            vulnerability["identifiers"][0]["url"] = link
+            vulnerability["links"] = [
+                {
+                    "url": link,
+                }
+            ]
+
+        return vulnerability
+
     def _create_license_vulnerability(self, record: Record) -> dict[str, Any] | None:
         details = record.vulnerability_details
         if not details:

{"golden_diff": "diff --git a/checkov/common/output/gitlab_sast.py b/checkov/common/output/gitlab_sast.py\n--- a/checkov/common/output/gitlab_sast.py\n+++ b/checkov/common/output/gitlab_sast.py\n@@ -79,21 +79,15 @@\n     def _create_iac_vulnerability(self, record: Record) -> dict[str, Any]:\n         severity = record.severity.name.lower() if record.severity else \"\"\n \n-        return {\n+        vulnerability: \"dict[str, Any]\" = {\n             \"id\": str(uuid4()),\n             \"identifiers\": [\n                 {\n                     \"name\": record.check_id,\n                     \"type\": \"checkov\",\n-                    \"url\": record.guideline,\n                     \"value\": record.check_id,\n                 }\n             ],\n-            \"links\": [\n-                {\n-                    \"url\": record.guideline,\n-                }\n-            ],\n             \"location\": {\n                 \"file\": record.repo_file_path.lstrip(\"/\"),\n                 \"start_line\": record.file_line_range[0],\n@@ -105,6 +99,17 @@\n             \"solution\": f\"Further info can be found {record.guideline}\",\n         }\n \n+        if record.guideline:\n+            # url can't be None\n+            vulnerability[\"identifiers\"][0][\"url\"] = record.guideline\n+            vulnerability[\"links\"] = [\n+                {\n+                    \"url\": record.guideline,\n+                }\n+            ]\n+\n+        return vulnerability\n+\n     def _create_cve_vulnerability(self, record: Record) -> dict[str, Any] | None:\n         details = record.vulnerability_details\n         if not details:\n@@ -113,21 +118,15 @@\n \n         severity = record.severity.name.lower() if record.severity else \"\"\n \n-        return {\n+        vulnerability: \"dict[str, Any]\" = {\n             \"id\": str(uuid4()),\n             \"identifiers\": [\n                 {\n                     \"name\": record.short_description,\n                     \"type\": \"cve\",\n-                    \"url\": details.get(\"link\"),\n                     \"value\": details[\"id\"],\n                 }\n             ],\n-            \"links\": [\n-                {\n-                    \"url\": details.get(\"link\"),\n-                }\n-            ],\n             \"location\": {\n                 \"file\": record.repo_file_path.lstrip(\"/\"),\n             },\n@@ -137,6 +136,18 @@\n             \"solution\": details.get(\"status\"),\n         }\n \n+        link = details.get(\"link\")\n+        if link:\n+            # url can't be None\n+            vulnerability[\"identifiers\"][0][\"url\"] = link\n+            vulnerability[\"links\"] = [\n+                {\n+                    \"url\": link,\n+                }\n+            ]\n+\n+        return vulnerability\n+\n     def _create_license_vulnerability(self, record: Record) -> dict[str, Any] | None:\n         details = record.vulnerability_details\n         if not details:\n", "issue": "GitLab SAST encounters error parsing the report\n**Describe the issue**\r\n`gitlab_sast` was added to the output in #4315. GitLab SAST produced the following error when attempting to parse the report.\r\n\r\n```\r\n[Schema] property '/vulnerabilities/0/identifiers/0/url' is not of type: string\r\n[Schema] property '/vulnerabilities/0/links/0/url' is not of type: string\r\n```\r\n\r\nI found that `url` value is set to `null` which is not supported e.g.\r\n\r\n```json\r\n    \"vulnerabilities\": [\r\n        {\r\n            \"id\": \"...\"\r\n            \"identifiers\": [\r\n                {\r\n                    \"name\": \"CKV_AWS_283\",\r\n                    \"type\": \"checkov\",\r\n                    \"url\": null,\r\n                    \"value\": \"CKV_AWS_283\"\r\n                }\r\n            ],\r\n            \"links\": [\r\n                {\r\n                    \"url\": null\r\n                }\r\n            ],\r\n           ...\r\n  ]\r\n```\r\n\r\n`url` is not a required field so instead of setting the value to `null`, drop the key altogether\r\n\r\nschema reference: https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom datetime import datetime\nfrom typing import TYPE_CHECKING, Any\nfrom uuid import uuid4\n\nfrom checkov.common.output.cyclonedx_consts import SCA_CHECKTYPES\nfrom checkov.version import version\n\nif TYPE_CHECKING:\n    from checkov.common.output.record import Record\n    from checkov.common.output.report import Report\n\nDEFAULT_SEVERITY_GITLAB_LEVEL = \"Unknown\"\nSEVERITY_TO_GITLAB_LEVEL = {\n    \"critical\": \"Critical\",\n    \"high\": \"High\",\n    \"medium\": \"Medium\",\n    \"low\": \"Low\",\n    \"none\": \"Info\",\n}\n\n\nclass GitLabSast:\n    def __init__(self, reports: list[Report]):\n        self.reports = reports\n\n        self.sast_json = self.create_sast_json()\n\n    def create_sast_json(self) -> dict[str, Any]:\n        return {\n            \"schema\": \"https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/v15.0.4/dist/sast-report-format.json\",\n            \"version\": \"15.0.4\",\n            \"scan\": self._create_scan(),\n            \"vulnerabilities\": self._create_vulnerabilities(),\n        }\n\n    def _create_scan(self) -> dict[str, Any]:\n        current_datetime = datetime.utcnow().strftime(\"%Y-%m-%dT%H:%M:%S\")\n        scanner = {\n            \"id\": \"checkov\",\n            \"name\": \"Checkov\",\n            \"url\": \"https://www.checkov.io/\",\n            \"vendor\": {\n                \"name\": \"Bridgecrew\",\n            },\n            \"version\": version,\n        }\n\n        return {\n            \"start_time\": current_datetime,  # needs to be done properly in a later stage\n            \"end_time\": current_datetime,\n            \"analyzer\": scanner,  # same for us\n            \"scanner\": scanner,\n            \"status\": \"success\",\n            \"type\": \"sast\",\n        }\n\n    def _create_vulnerabilities(self) -> list[dict[str, Any]]:\n        vulnerabilities = []\n\n        for report in self.reports:\n            if report.check_type in SCA_CHECKTYPES:\n                for check in report.failed_checks:\n                    vulnerability = None\n                    if check.check_id.startswith(\"BC_LIC\"):\n                        vulnerability = self._create_license_vulnerability(record=check)\n                    elif check.check_id.startswith((\"BC_VUL\", \"CKV_CVE\")):\n                        vulnerability = self._create_cve_vulnerability(record=check)\n\n                    if vulnerability:\n                        vulnerabilities.append(vulnerability)\n            else:\n                for check in report.failed_checks:\n                    vulnerabilities.append(self._create_iac_vulnerability(record=check))\n\n        return vulnerabilities\n\n    def _create_iac_vulnerability(self, record: Record) -> dict[str, Any]:\n        severity = record.severity.name.lower() if record.severity else \"\"\n\n        return {\n            \"id\": str(uuid4()),\n            \"identifiers\": [\n                {\n                    \"name\": record.check_id,\n                    \"type\": \"checkov\",\n                    \"url\": record.guideline,\n                    \"value\": record.check_id,\n                }\n            ],\n            \"links\": [\n                {\n                    \"url\": record.guideline,\n                }\n            ],\n            \"location\": {\n                \"file\": record.repo_file_path.lstrip(\"/\"),\n                \"start_line\": record.file_line_range[0],\n                \"end_line\": record.file_line_range[1],\n            },\n            \"name\": record.check_name,\n            \"description\": f\"Further info can be found {record.guideline}\",\n            \"severity\": SEVERITY_TO_GITLAB_LEVEL.get(severity, DEFAULT_SEVERITY_GITLAB_LEVEL),\n            \"solution\": f\"Further info can be found {record.guideline}\",\n        }\n\n    def _create_cve_vulnerability(self, record: Record) -> dict[str, Any] | None:\n        details = record.vulnerability_details\n        if not details:\n            # this shouldn't happen\n            return None\n\n        severity = record.severity.name.lower() if record.severity else \"\"\n\n        return {\n            \"id\": str(uuid4()),\n            \"identifiers\": [\n                {\n                    \"name\": record.short_description,\n                    \"type\": \"cve\",\n                    \"url\": details.get(\"link\"),\n                    \"value\": details[\"id\"],\n                }\n            ],\n            \"links\": [\n                {\n                    \"url\": details.get(\"link\"),\n                }\n            ],\n            \"location\": {\n                \"file\": record.repo_file_path.lstrip(\"/\"),\n            },\n            \"name\": record.short_description,\n            \"description\": details.get(\"description\"),\n            \"severity\": SEVERITY_TO_GITLAB_LEVEL.get(severity, DEFAULT_SEVERITY_GITLAB_LEVEL),\n            \"solution\": details.get(\"status\"),\n        }\n\n    def _create_license_vulnerability(self, record: Record) -> dict[str, Any] | None:\n        details = record.vulnerability_details\n        if not details:\n            # this shouldn't happen\n            return None\n\n        return {\n            \"id\": str(uuid4()),\n            \"identifiers\": [\n                {\n                    \"name\": record.check_id,\n                    \"type\": \"license\",\n                    \"value\": record.check_id,\n                }\n            ],\n            \"location\": {\n                \"file\": record.repo_file_path.lstrip(\"/\"),\n            },\n            \"name\": record.short_description,\n            \"description\": f\"Package {details['package_name']}@{details['package_version']} has license {details['license']}\",\n        }\n", "path": "checkov/common/output/gitlab_sast.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom datetime import datetime\nfrom typing import TYPE_CHECKING, Any\nfrom uuid import uuid4\n\nfrom checkov.common.output.cyclonedx_consts import SCA_CHECKTYPES\nfrom checkov.version import version\n\nif TYPE_CHECKING:\n    from checkov.common.output.record import Record\n    from checkov.common.output.report import Report\n\nDEFAULT_SEVERITY_GITLAB_LEVEL = \"Unknown\"\nSEVERITY_TO_GITLAB_LEVEL = {\n    \"critical\": \"Critical\",\n    \"high\": \"High\",\n    \"medium\": \"Medium\",\n    \"low\": \"Low\",\n    \"none\": \"Info\",\n}\n\n\nclass GitLabSast:\n    def __init__(self, reports: list[Report]):\n        self.reports = reports\n\n        self.sast_json = self.create_sast_json()\n\n    def create_sast_json(self) -> dict[str, Any]:\n        return {\n            \"schema\": \"https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/raw/v15.0.4/dist/sast-report-format.json\",\n            \"version\": \"15.0.4\",\n            \"scan\": self._create_scan(),\n            \"vulnerabilities\": self._create_vulnerabilities(),\n        }\n\n    def _create_scan(self) -> dict[str, Any]:\n        current_datetime = datetime.utcnow().strftime(\"%Y-%m-%dT%H:%M:%S\")\n        scanner = {\n            \"id\": \"checkov\",\n            \"name\": \"Checkov\",\n            \"url\": \"https://www.checkov.io/\",\n            \"vendor\": {\n                \"name\": \"Bridgecrew\",\n            },\n            \"version\": version,\n        }\n\n        return {\n            \"start_time\": current_datetime,  # needs to be done properly in a later stage\n            \"end_time\": current_datetime,\n            \"analyzer\": scanner,  # same for us\n            \"scanner\": scanner,\n            \"status\": \"success\",\n            \"type\": \"sast\",\n        }\n\n    def _create_vulnerabilities(self) -> list[dict[str, Any]]:\n        vulnerabilities = []\n\n        for report in self.reports:\n            if report.check_type in SCA_CHECKTYPES:\n                for check in report.failed_checks:\n                    vulnerability = None\n                    if check.check_id.startswith(\"BC_LIC\"):\n                        vulnerability = self._create_license_vulnerability(record=check)\n                    elif check.check_id.startswith((\"BC_VUL\", \"CKV_CVE\")):\n                        vulnerability = self._create_cve_vulnerability(record=check)\n\n                    if vulnerability:\n                        vulnerabilities.append(vulnerability)\n            else:\n                for check in report.failed_checks:\n                    vulnerabilities.append(self._create_iac_vulnerability(record=check))\n\n        return vulnerabilities\n\n    def _create_iac_vulnerability(self, record: Record) -> dict[str, Any]:\n        severity = record.severity.name.lower() if record.severity else \"\"\n\n        vulnerability: \"dict[str, Any]\" = {\n            \"id\": str(uuid4()),\n            \"identifiers\": [\n                {\n                    \"name\": record.check_id,\n                    \"type\": \"checkov\",\n                    \"value\": record.check_id,\n                }\n            ],\n            \"location\": {\n                \"file\": record.repo_file_path.lstrip(\"/\"),\n                \"start_line\": record.file_line_range[0],\n                \"end_line\": record.file_line_range[1],\n            },\n            \"name\": record.check_name,\n            \"description\": f\"Further info can be found {record.guideline}\",\n            \"severity\": SEVERITY_TO_GITLAB_LEVEL.get(severity, DEFAULT_SEVERITY_GITLAB_LEVEL),\n            \"solution\": f\"Further info can be found {record.guideline}\",\n        }\n\n        if record.guideline:\n            # url can't be None\n            vulnerability[\"identifiers\"][0][\"url\"] = record.guideline\n            vulnerability[\"links\"] = [\n                {\n                    \"url\": record.guideline,\n                }\n            ]\n\n        return vulnerability\n\n    def _create_cve_vulnerability(self, record: Record) -> dict[str, Any] | None:\n        details = record.vulnerability_details\n        if not details:\n            # this shouldn't happen\n            return None\n\n        severity = record.severity.name.lower() if record.severity else \"\"\n\n        vulnerability: \"dict[str, Any]\" = {\n            \"id\": str(uuid4()),\n            \"identifiers\": [\n                {\n                    \"name\": record.short_description,\n                    \"type\": \"cve\",\n                    \"value\": details[\"id\"],\n                }\n            ],\n            \"location\": {\n                \"file\": record.repo_file_path.lstrip(\"/\"),\n            },\n            \"name\": record.short_description,\n            \"description\": details.get(\"description\"),\n            \"severity\": SEVERITY_TO_GITLAB_LEVEL.get(severity, DEFAULT_SEVERITY_GITLAB_LEVEL),\n            \"solution\": details.get(\"status\"),\n        }\n\n        link = details.get(\"link\")\n        if link:\n            # url can't be None\n            vulnerability[\"identifiers\"][0][\"url\"] = link\n            vulnerability[\"links\"] = [\n                {\n                    \"url\": link,\n                }\n            ]\n\n        return vulnerability\n\n    def _create_license_vulnerability(self, record: Record) -> dict[str, Any] | None:\n        details = record.vulnerability_details\n        if not details:\n            # this shouldn't happen\n            return None\n\n        return {\n            \"id\": str(uuid4()),\n            \"identifiers\": [\n                {\n                    \"name\": record.check_id,\n                    \"type\": \"license\",\n                    \"value\": record.check_id,\n                }\n            ],\n            \"location\": {\n                \"file\": record.repo_file_path.lstrip(\"/\"),\n            },\n            \"name\": record.short_description,\n            \"description\": f\"Package {details['package_name']}@{details['package_version']} has license {details['license']}\",\n        }\n", "path": "checkov/common/output/gitlab_sast.py"}]}