Question: I'm having trouble getting dbus to connect:  try: logging.debug("Attempting to connect to D-Bus.") self.bus = SessionBus() self.keepass_service = self.bus.get("org.keepassxc.KeePassXC.MainWindow", "/org/keepassxc/KeePassXC/MainWindow") # self.keepass_service = self.bus.get("org.keepassxc.KeePassXC", "/org/keepassxc/KeePassXC/") # self.keepass_service = self.bus.get("org.keepassxc.KeePassXC.MainWindow")  Dbus.Listnames shows:  $ dbus-send --print-reply --dest=org.freedesktop.DBus --type=method_call /org/freedesktop/DBus org.freedesktop.DBus.ListNames method return time=1729375987.604568 sender=org.freedesktop.DBus -> destination=:1.826 serial=3 reply_serial=2 array [ string "org.freedesktop.DBus" string ":1.469" string "org.freedesktop.Notifications" string "org.freedesktop.PowerManagement" string ":1.7" string "org.keepassxc.KeePassXC.MainWindow"  This version produces this error:  self.keepass_service = self.bus.get("org.keepassxc.KeePassXC.MainWindow", "/org/keepassxc/KeePassXC/MainWindow") ERROR:root:Error message: g-dbus-error-quark: GDBus.Error:org.freedesktop.DBus.Error.UnknownObject: No such object path '/org/keepassxc/KeePassXC/MainWindow' (41)  This version produces this error:  self.keepass_service = self.bus.get("org.keepassxc.KeePassXC", "/org/keepassxc/KeePassXC/") (process:607644): GLib-GIO-CRITICAL **: 16:18:39.599: g_dbus_connection_call_sync_internal: assertion 'object_path != NULL && g_variant_is_object_path (object_path)' failed ERROR:root:Failed to connect to KeePassXC D-Bus interface. ERROR:root:Error message: 'no such object; you might need to pass object path as the 2nd argument for get()'  I've tried adding a time delay in case it was a race condition. I've tried with a keepassxc instance already running. I don't know where to go next? Here's the code in full context: from pydbus import SessionBus import logging import os import subprocess from gi.repository import GLib import time # Set up logging configuration logging.basicConfig(level=logging.DEBUG) # Set logging level to debug class KeePassXCManager: def __init__(self, db_path, password=None, keyfile=None, appimage_path=None): logging.debug("Initializing KeePassXCManager") self.db_path = db_path self.password = password self.keyfile = keyfile self.kp = None self.keepass_command = [] # Set default path to the KeePassXC AppImage in ~/Applications self.appimage_path = appimage_path or os.path.expanduser("~/Applications/KeePassXC.appimage") logging.debug(f"AppImage path set to: {self.appimage_path}") # Determine the KeePassXC launch command self._set_keepassxc_command() self._ensure_keepassxc_running() # Set up the D-Bus connection to KeePassXC self.bus = SessionBus() self.keepass_service = None self._connect_to_dbus() # Open the database once the manager is initialized if not self.open_database(): logging.error("Failed to open the database during initialization.") def _set_keepassxc_command(self): """Sets the command to launch KeePassXC.""" try: if self._is_keepassxc_installed(): logging.info("Using installed KeePassXC version.") self.keepass_command = ["keepassxc"] elif os.path.isfile(self.appimage_path) and os.access(self.appimage_path, os.X_OK): logging.info(f"KeePassXC AppImage is executable at {self.appimage_path}") self.keepass_command = [self.appimage_path] else: logging.error("KeePassXC is not installed or AppImage is not executable.") raise RuntimeError("KeePassXC is not installed. Please install it or provide a valid AppImage.") logging.debug(f"Final KeePassXC command set: {self.keepass_command}") except Exception as e: logging.error(f"Error setting KeePassXC command: {e}") raise def _is_keepassxc_installed(self): """Checks if KeePassXC is installed on the system.""" logging.debug("Checking if KeePassXC is installed via package manager") try: result = subprocess.run(["which", "keepassxc"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if result.returncode == 0: logging.info(f"KeePassXC found at {result.stdout.decode().strip()}") return True else: logging.warning("KeePassXC is not installed via package manager.") return False except Exception as e: logging.error(f"Error checking KeePassXC installation: {e}") return False def _ensure_keepassxc_running(self): """Checks if KeePassXC is running and starts it if not.""" logging.debug("Checking if KeePassXC is running") try: # Check if KeePassXC is running using pgrep result = subprocess.run(["pgrep", "-x", "keepassxc"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if result.returncode != 0: logging.info("KeePassXC is not running. Starting KeePassXC.") # Start KeePassXC subprocess.Popen(self.keepass_command) # Optionally, wait for a short time to allow KeePassXC to start GLib.idle_add(lambda: None) # Allows the GUI to initialize else: logging.info("KeePassXC is already running.") except Exception as e: logging.error(f"Error checking or starting KeePassXC: {e}") def _construct_open_command(self): """Constructs the command to open the KeePassXC database.""" command = [self.keepass_command[0], self.db_path] if self.password: command.append("--pw-stdin") logging.debug(f"Command includes password for opening database: {self.db_path}") if self.keyfile: command.append(f"--keyfile={self.keyfile}") logging.debug(f"Command includes keyfile for opening database: {self.keyfile}") logging.debug(f"Final command to open KeePassXC database: {command}") return command if self.password or self.keyfile else None def _clear_sensitive_data(self): """Clears sensitive data from memory.""" logging.debug("Clearing sensitive data from memory") self.password = None self.keyfile = None self.db_path = None def _connect_to_dbus(self): """Connects to the KeePassXC D-Bus interface.""" try: logging.debug("Attempting to connect to D-Bus.") self.bus = SessionBus() # self.keepass_service = self.bus.get("org.keepassxc.KeePassXC.MainWindow", "/org/keepassxc/KeePassXC/MainWindow") self.keepass_service = self.bus.get("org.keepassxc.KeePassXC", "/org/keepassxc/KeePassXC/") # self.keepass_service = self.bus.get("org.keepassxc.KeePassXC.MainWindow") # self.keepass_service = self.bus.get("org.KeePassXC.MainWindow", "/org/KeePassXC/MainWindow") if self.keepass_service: logging.info("Successfully connected to KeePassXC D-Bus interface.") else: logging.error("KeePassXC D-Bus interface is not available.") except Exception as e: logging.error("Failed to connect to KeePassXC D-Bus interface.") logging.error(f"Error message: {e}") services = self.bus.get_services() logging.error(f"Available D-Bus services: {services}") def open_database(self): """Opens the KeePassXC database using D-Bus.""" try: if not self.keepass_service: logging.error("KeePassXC D-Bus service is not available.") return False logging.info(f"Opening database: {self.db_path}") # Prepare parameters for the D-Bus call password = self.password or "" keyfile = self.keyfile or "" # Call the D-Bus method with parameters directly response = self.keepass_service.openDatabase(self.db_path, password, keyfile) if response: logging.info("Database opened successfully via D-Bus.") return True else: logging.error("Failed to open database via D-Bus.") return False except Exception as e: logging.error(f"An error occurred while opening the database: {e}") return False def unlock_database(self): """Unlocks the KeePassXC database with the password via D-Bus.""" try: if not self.keepass_service: logging.error("KeePassXC D-Bus service is not available.") return False logging.info("Unlocking database with the provided password.") response = self.keepass_service.unlockDatabase(self.password) if response: logging.info("Database unlocked successfully via D-Bus.") return True else: logging.error("Failed to unlock database via D-Bus.") return False except Exception as e: logging.error(f"An error occurred while unlocking the database: {e}") return False 

Answer: You are assuming that the object path always follows the naming of the service itself. That's not always the case – a service can export many different object paths, and does not strictly need to follow any naming style (i.e. there isn't an enforced rule that all object paths start with the service name, much less that there be one that exactly matches it; both are merely conventions). KeePassXC is a Qt-based app, and many of those famously do not care to follow the usual D-Bus convention of using the service name as the "base" for object paths; instead, the old KDE3 DCOP (pre-D-Bus) style with all objects rooted directly at / remains common among Qt programs. Looking through busctl or D-Spy (or the older D-Feet), it seems that KeePassXC does not follow the D-Bus conventions of object naming, and the only object it exposes is at the path /keepassxc. $ busctl --user tree org.keepassxc.KeePassXC.MainWindow └─ /keepassxc  $ gdbus introspect -e -d org.keepassxc.KeePassXC.MainWindow -o / -r -p node / { node /keepassxc { }; };  So you need to call: bus.get("org.keepassxc.KeePassXC.MainWindow", "/keepassxc")  Note that since an object can have methods under several interfaces, some D-Bus bindings automatically use introspection to resolve unambiguous method names to the correct interface, but e.g. dbus-python would require you to explicitly use dbus.Interface(obj…).Foo(…) or obj.Foo(…, dbus_interface=…). Likewise the interface names don't need to match the service name – although it seems that KeePassXC has used the same string for both, but the .MainWindow suffix is pretty odd for a service name to have when all windows of an app belong to the same process (while being a perfectly normal name for an interface that holds main window-related methods).  Generally instead of dbus-send I'd suggest the slightly less verbose systemd or GLib2 tools (both of which support showing the introspection XML from the service): $ busctl --user introspect org.keepassxc.KeePassXC.MainWindow /keepassxc $ busctl --user call ... $ gdbus introspect -e -d org.keepassxc.KeePassXC.MainWindow -o /keepassxc $ gdbus call -e ...