We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
bug: When meltano.yml is empty, no error message is printed. Rather, it just mentions to reach out to community
### Meltano Version

2.19.0

### Python Version

3.9

### Bug scope

CLI (options, error messages, logging, etc.)

### Operating System

Windows - WSL(Ubuntu)

### Description

when `meltano.yml` is empty, `cli`(`meltano.cli.__init__.py: 105`) raises `EmptyMeltanoFileException` exception whenever we try to run any command such as `meltano add` or `meltano ui`. But, since there's no exception message, it just prints the troubleshooting message and blank lines as follows

```
Need help fixing this problem? Visit http://melta.no/ for troubleshooting steps, or to
join our friendly Slack community.

```


### Code

_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: `src/meltano/core/error.py`
Content:
```
1 """Base Error classes."""
2 
3 from __future__ import annotations
4 
5 import typing as t
6 from asyncio.streams import StreamReader
7 from asyncio.subprocess import Process
8 from enum import Enum
9 
10 if t.TYPE_CHECKING:
11     from meltano.core.project import Project
12 
13 
14 class ExitCode(int, Enum):  # noqa: D101
15     OK = 0
16     FAIL = 1
17     NO_RETRY = 2
18 
19 
20 class MeltanoError(Exception):
21     """Base class for all user-facing errors."""
22 
23     def __init__(
24         self,
25         reason: str,
26         instruction: str | None = None,
27         *args: t.Any,
28         **kwargs: t.Any,
29     ) -> None:
30         """Initialize a MeltanoError.
31 
32         Args:
33             reason: A short explanation of the error.
34             instruction: A short instruction on how to fix the error.
35             args: Additional arguments to pass to the base exception class.
36             kwargs: Keyword arguments to pass to the base exception class.
37         """
38         self.reason = reason
39         self.instruction = instruction
40         super().__init__(reason, instruction, *args, **kwargs)
41 
42     def __str__(self) -> str:
43         """Return a string representation of the error.
44 
45         Returns:
46             A string representation of the error.
47         """
48         return (
49             f"{self.reason}. {self.instruction}."
50             if self.instruction
51             else f"{self.reason}."
52         )
53 
54 
55 class Error(Exception):
56     """Base exception for ELT errors."""
57 
58     def exit_code(self):  # noqa: D102
59         return ExitCode.FAIL
60 
61 
62 class ExtractError(Error):
63     """Error in the extraction process, like API errors."""
64 
65     def exit_code(self):  # noqa: D102
66         return ExitCode.NO_RETRY
67 
68 
69 class AsyncSubprocessError(Exception):
70     """Happens when an async subprocess exits with a resultcode != 0."""
71 
72     def __init__(
73         self,
74         message: str,
75         process: Process,
76         stderr: str | None = None,
77     ):  # noqa: DAR101
78         """Initialize AsyncSubprocessError."""
79         self.process = process
80         self._stderr: str | StreamReader | None = stderr or process.stderr
81         super().__init__(message)
82 
83     @property
84     async def stderr(self) -> str | None:
85         """Return the output of the process to stderr."""
86         if not self._stderr:  # noqa: DAR201
87             return None
88         elif not isinstance(self._stderr, str):
89             stream = await self._stderr.read()
90             self._stderr = stream.decode("utf-8")
91 
92         return self._stderr
93 
94 
95 class PluginInstallError(Exception):
96     """Exception for when a plugin fails to install."""
97 
98 
99 class PluginInstallWarning(Exception):
100     """Exception for when a plugin optional optional step fails to install."""
101 
102 
103 class EmptyMeltanoFileException(Exception):
104     """Exception for empty meltano.yml file."""
105 
106 
107 class MeltanoConfigurationError(MeltanoError):
108     """Exception for when Meltano is inproperly configured."""
109 
110 
111 class ProjectNotFound(Error):
112     """A Project is instantiated outside of a meltano project structure."""
113 
114     def __init__(self, project: Project):
115         """Instantiate the error.
116 
117         Args:
118             project: the name of the project which cannot be found
119         """
120         super().__init__(
121             f"Cannot find `{project.meltanofile}`. Are you in a meltano project?",
122         )
123 
124 
125 class ProjectReadonly(Error):
126     """Attempting to update a readonly project."""
127 
128     def __init__(self):
129         """Instantiate the error."""
130         super().__init__("This Meltano project is deployed as read-only")
131
```
--- 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/src/meltano/core/error.py b/src/meltano/core/error.py
--- a/src/meltano/core/error.py
+++ b/src/meltano/core/error.py
@@ -100,9 +100,15 @@
     """Exception for when a plugin optional optional step fails to install."""
 
 
-class EmptyMeltanoFileException(Exception):
+class EmptyMeltanoFileException(MeltanoError):
     """Exception for empty meltano.yml file."""
 
+    def __init__(self) -> None:
+        """Instantiate the error."""
+        reason = "Your meltano.yml file is empty"
+        instruction = "Please update your meltano file with a valid configuration"
+        super().__init__(reason, instruction)
+
 
 class MeltanoConfigurationError(MeltanoError):
     """Exception for when Meltano is inproperly configured."""

{"golden_diff": "diff --git a/src/meltano/core/error.py b/src/meltano/core/error.py\n--- a/src/meltano/core/error.py\n+++ b/src/meltano/core/error.py\n@@ -100,9 +100,15 @@\n     \"\"\"Exception for when a plugin optional optional step fails to install.\"\"\"\n \n \n-class EmptyMeltanoFileException(Exception):\n+class EmptyMeltanoFileException(MeltanoError):\n     \"\"\"Exception for empty meltano.yml file.\"\"\"\n \n+    def __init__(self) -> None:\n+        \"\"\"Instantiate the error.\"\"\"\n+        reason = \"Your meltano.yml file is empty\"\n+        instruction = \"Please update your meltano file with a valid configuration\"\n+        super().__init__(reason, instruction)\n+\n \n class MeltanoConfigurationError(MeltanoError):\n     \"\"\"Exception for when Meltano is inproperly configured.\"\"\"\n", "issue": "bug: When meltano.yml is empty, no error message is printed. Rather, it just mentions to reach out to community\n### Meltano Version\r\n\r\n2.19.0\r\n\r\n### Python Version\r\n\r\n3.9\r\n\r\n### Bug scope\r\n\r\nCLI (options, error messages, logging, etc.)\r\n\r\n### Operating System\r\n\r\nWindows - WSL(Ubuntu)\r\n\r\n### Description\r\n\r\nwhen `meltano.yml` is empty, `cli`(`meltano.cli.__init__.py: 105`) raises `EmptyMeltanoFileException` exception whenever we try to run any command such as `meltano add` or `meltano ui`. But, since there's no exception message, it just prints the troubleshooting message and blank lines as follows\r\n\r\n```\r\nNeed help fixing this problem? Visit http://melta.no/ for troubleshooting steps, or to\r\njoin our friendly Slack community.\r\n\r\n```\r\n\r\n\r\n### Code\r\n\r\n_No response_\n", "before_files": [{"content": "\"\"\"Base Error classes.\"\"\"\n\nfrom __future__ import annotations\n\nimport typing as t\nfrom asyncio.streams import StreamReader\nfrom asyncio.subprocess import Process\nfrom enum import Enum\n\nif t.TYPE_CHECKING:\n    from meltano.core.project import Project\n\n\nclass ExitCode(int, Enum):  # noqa: D101\n    OK = 0\n    FAIL = 1\n    NO_RETRY = 2\n\n\nclass MeltanoError(Exception):\n    \"\"\"Base class for all user-facing errors.\"\"\"\n\n    def __init__(\n        self,\n        reason: str,\n        instruction: str | None = None,\n        *args: t.Any,\n        **kwargs: t.Any,\n    ) -> None:\n        \"\"\"Initialize a MeltanoError.\n\n        Args:\n            reason: A short explanation of the error.\n            instruction: A short instruction on how to fix the error.\n            args: Additional arguments to pass to the base exception class.\n            kwargs: Keyword arguments to pass to the base exception class.\n        \"\"\"\n        self.reason = reason\n        self.instruction = instruction\n        super().__init__(reason, instruction, *args, **kwargs)\n\n    def __str__(self) -> str:\n        \"\"\"Return a string representation of the error.\n\n        Returns:\n            A string representation of the error.\n        \"\"\"\n        return (\n            f\"{self.reason}. {self.instruction}.\"\n            if self.instruction\n            else f\"{self.reason}.\"\n        )\n\n\nclass Error(Exception):\n    \"\"\"Base exception for ELT errors.\"\"\"\n\n    def exit_code(self):  # noqa: D102\n        return ExitCode.FAIL\n\n\nclass ExtractError(Error):\n    \"\"\"Error in the extraction process, like API errors.\"\"\"\n\n    def exit_code(self):  # noqa: D102\n        return ExitCode.NO_RETRY\n\n\nclass AsyncSubprocessError(Exception):\n    \"\"\"Happens when an async subprocess exits with a resultcode != 0.\"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        process: Process,\n        stderr: str | None = None,\n    ):  # noqa: DAR101\n        \"\"\"Initialize AsyncSubprocessError.\"\"\"\n        self.process = process\n        self._stderr: str | StreamReader | None = stderr or process.stderr\n        super().__init__(message)\n\n    @property\n    async def stderr(self) -> str | None:\n        \"\"\"Return the output of the process to stderr.\"\"\"\n        if not self._stderr:  # noqa: DAR201\n            return None\n        elif not isinstance(self._stderr, str):\n            stream = await self._stderr.read()\n            self._stderr = stream.decode(\"utf-8\")\n\n        return self._stderr\n\n\nclass PluginInstallError(Exception):\n    \"\"\"Exception for when a plugin fails to install.\"\"\"\n\n\nclass PluginInstallWarning(Exception):\n    \"\"\"Exception for when a plugin optional optional step fails to install.\"\"\"\n\n\nclass EmptyMeltanoFileException(Exception):\n    \"\"\"Exception for empty meltano.yml file.\"\"\"\n\n\nclass MeltanoConfigurationError(MeltanoError):\n    \"\"\"Exception for when Meltano is inproperly configured.\"\"\"\n\n\nclass ProjectNotFound(Error):\n    \"\"\"A Project is instantiated outside of a meltano project structure.\"\"\"\n\n    def __init__(self, project: Project):\n        \"\"\"Instantiate the error.\n\n        Args:\n            project: the name of the project which cannot be found\n        \"\"\"\n        super().__init__(\n            f\"Cannot find `{project.meltanofile}`. Are you in a meltano project?\",\n        )\n\n\nclass ProjectReadonly(Error):\n    \"\"\"Attempting to update a readonly project.\"\"\"\n\n    def __init__(self):\n        \"\"\"Instantiate the error.\"\"\"\n        super().__init__(\"This Meltano project is deployed as read-only\")\n", "path": "src/meltano/core/error.py"}], "after_files": [{"content": "\"\"\"Base Error classes.\"\"\"\n\nfrom __future__ import annotations\n\nimport typing as t\nfrom asyncio.streams import StreamReader\nfrom asyncio.subprocess import Process\nfrom enum import Enum\n\nif t.TYPE_CHECKING:\n    from meltano.core.project import Project\n\n\nclass ExitCode(int, Enum):  # noqa: D101\n    OK = 0\n    FAIL = 1\n    NO_RETRY = 2\n\n\nclass MeltanoError(Exception):\n    \"\"\"Base class for all user-facing errors.\"\"\"\n\n    def __init__(\n        self,\n        reason: str,\n        instruction: str | None = None,\n        *args: t.Any,\n        **kwargs: t.Any,\n    ) -> None:\n        \"\"\"Initialize a MeltanoError.\n\n        Args:\n            reason: A short explanation of the error.\n            instruction: A short instruction on how to fix the error.\n            args: Additional arguments to pass to the base exception class.\n            kwargs: Keyword arguments to pass to the base exception class.\n        \"\"\"\n        self.reason = reason\n        self.instruction = instruction\n        super().__init__(reason, instruction, *args, **kwargs)\n\n    def __str__(self) -> str:\n        \"\"\"Return a string representation of the error.\n\n        Returns:\n            A string representation of the error.\n        \"\"\"\n        return (\n            f\"{self.reason}. {self.instruction}.\"\n            if self.instruction\n            else f\"{self.reason}.\"\n        )\n\n\nclass Error(Exception):\n    \"\"\"Base exception for ELT errors.\"\"\"\n\n    def exit_code(self):  # noqa: D102\n        return ExitCode.FAIL\n\n\nclass ExtractError(Error):\n    \"\"\"Error in the extraction process, like API errors.\"\"\"\n\n    def exit_code(self):  # noqa: D102\n        return ExitCode.NO_RETRY\n\n\nclass AsyncSubprocessError(Exception):\n    \"\"\"Happens when an async subprocess exits with a resultcode != 0.\"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        process: Process,\n        stderr: str | None = None,\n    ):  # noqa: DAR101\n        \"\"\"Initialize AsyncSubprocessError.\"\"\"\n        self.process = process\n        self._stderr: str | StreamReader | None = stderr or process.stderr\n        super().__init__(message)\n\n    @property\n    async def stderr(self) -> str | None:\n        \"\"\"Return the output of the process to stderr.\"\"\"\n        if not self._stderr:  # noqa: DAR201\n            return None\n        elif not isinstance(self._stderr, str):\n            stream = await self._stderr.read()\n            self._stderr = stream.decode(\"utf-8\")\n\n        return self._stderr\n\n\nclass PluginInstallError(Exception):\n    \"\"\"Exception for when a plugin fails to install.\"\"\"\n\n\nclass PluginInstallWarning(Exception):\n    \"\"\"Exception for when a plugin optional optional step fails to install.\"\"\"\n\n\nclass EmptyMeltanoFileException(MeltanoError):\n    \"\"\"Exception for empty meltano.yml file.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Instantiate the error.\"\"\"\n        reason = \"Your meltano.yml file is empty\"\n        instruction = \"Please update your meltano file with a valid configuration\"\n        super().__init__(reason, instruction)\n\n\nclass MeltanoConfigurationError(MeltanoError):\n    \"\"\"Exception for when Meltano is inproperly configured.\"\"\"\n\n\nclass ProjectNotFound(Error):\n    \"\"\"A Project is instantiated outside of a meltano project structure.\"\"\"\n\n    def __init__(self, project: Project):\n        \"\"\"Instantiate the error.\n\n        Args:\n            project: the name of the project which cannot be found\n        \"\"\"\n        super().__init__(\n            f\"Cannot find `{project.meltanofile}`. Are you in a meltano project?\",\n        )\n\n\nclass ProjectReadonly(Error):\n    \"\"\"Attempting to update a readonly project.\"\"\"\n\n    def __init__(self):\n        \"\"\"Instantiate the error.\"\"\"\n        super().__init__(\"This Meltano project is deployed as read-only\")\n", "path": "src/meltano/core/error.py"}]}