diff --git a/pyinfra_cli/util.py b/pyinfra_cli/util.py
index 95ea7b62e..111dc96f1 100644
--- a/pyinfra_cli/util.py
+++ b/pyinfra_cli/util.py
@@ -15,6 +15,7 @@
 import gevent
 
 from pyinfra import logger, state
+from pyinfra.api import FactBase
 from pyinfra.api.command import PyinfraCommand
 from pyinfra.api.exceptions import PyinfraError
 from pyinfra.api.host import HostData
@@ -153,6 +154,37 @@ def parse_cli_arg(arg):
     return arg
 
 
+def get_module_available_actions(module: ModuleType) -> dict[str, list[str]]:
+    """
+    Lists operations and facts available in a module.
+
+    Args:
+        module (ModuleType): The module to inspect.
+
+    Returns:
+        dict: A dictionary with keys 'operations' and 'facts', each containing a list of names.
+    """
+    available_actions: dict[str, list[str]] = {
+        "operations": [],
+        "facts": [],
+    }
+
+    for name, obj in module.__dict__.items():
+        # Check if it's a decorated operation
+        if callable(obj) and getattr(obj, "is_idempotent", None) is not None:
+            available_actions["operations"].append(name)
+
+        # Check if it's a FactBase subclass
+        elif (
+            isinstance(obj, type)
+            and issubclass(obj, FactBase)
+            and obj.__module__ == module.__name__
+        ):
+            available_actions["facts"].append(name)
+
+    return available_actions
+
+
 def try_import_module_attribute(path, prefix=None, raise_for_none=True):
     if ":" in path:
         # Allow a.module.name:function syntax
@@ -189,7 +221,36 @@ def try_import_module_attribute(path, prefix=None, raise_for_none=True):
     attr = getattr(module, attr_name, None)
     if attr is None:
         if raise_for_none:
-            raise CliError(f"No such attribute in module {possible_modules[0]}: {attr_name}")
+            extra_info = []
+            module_name = getattr(module, "__name__", str(module))
+
+            if prefix == "pyinfra.operations":
+                # List classes of type OperationMeta
+                available_operations = get_module_available_actions(module)["operations"]
+                if available_operations:
+                    extra_info.append(
+                        f"Available operations are: {', '.join(available_operations)}"
+                    )
+                else:
+                    extra_info.append(
+                        "No operations found. Maybe you have a file or folder named "
+                        f"`{str(module_name)}` in the current folder ?"
+                    )
+
+            elif prefix == "pyinfra.facts":
+                # List classes of type FactBase
+                available_facts = get_module_available_actions(module)["facts"]
+                if available_facts:
+                    extra_info.append(f"Available facts are: {', '.join(available_facts)}")
+                else:
+                    extra_info.append(
+                        "No facts found. Maybe you have a file or folder named "
+                        f"`{str(module_name)}` in the current folder ?"
+                    )
+
+            message = [f"No such attribute in module {possible_modules[0]}: {attr_name}"]
+
+            raise CliError("\n".join(message + extra_info))
         return
 
     return attr
diff --git a/tests/test_cli/test_cli_exceptions.py b/tests/test_cli/test_cli_exceptions.py
index 7cac5f15a..e20a5797d 100644
--- a/tests/test_cli/test_cli_exceptions.py
+++ b/tests/test_cli/test_cli_exceptions.py
@@ -44,7 +44,13 @@ def test_no_fact_module(self):
     def test_no_fact_cls(self):
         self.assert_cli_exception(
             ["my-server.net", "fact", "server.NotAFact"],
-            "No such attribute in module server: NotAFact",
+            (
+                "No such attribute in module server: NotAFact\n"
+                "Available facts in module are: User, Home, Path, TmpDir, Hostname, Kernel, "
+                "KernelVersion, Os, OsVersion, Arch, Command, Which, Date, MacosVersion, Mounts, "
+                "KernelModules, LsbRelease, OsRelease, Sysctl, Groups, Users, LinuxDistribution, "
+                "Selinux, LinuxGui, Locales, SecurityLimits"
+            ),
         )
 
 
diff --git a/tests/test_cli/test_cli_util.py b/tests/test_cli/test_cli_util.py
index 776510f14..6596ab3b0 100644
--- a/tests/test_cli/test_cli_util.py
+++ b/tests/test_cli/test_cli_util.py
@@ -36,7 +36,11 @@ def test_setup_no_op(self):
         with self.assertRaises(CliError) as context:
             get_func_and_args(("server.no",))
 
-        assert context.exception.message == "No such attribute in module server: no"
+        assert context.exception.message == (
+            "No such attribute in module server: no\n"
+            "No operations found. Maybe you have a file or folder named "
+            "`pyinfra.operations.server` in the current folder ?"
+        )
 
     def test_setup_op_and_args(self):
         commands = ("pyinfra.operations.server.user", "one", "two", "hello=world")