From 3d4de89fd5464e68121d3f9c0c5fbddc6e9b9113 Mon Sep 17 00:00:00 2001 From: Chuck Date: Sat, 23 May 2026 16:32:04 -0400 Subject: [PATCH] Treat system-managed pip packages as satisfied for dependency marker When a plugin's requirements.txt includes a package installed via the system package manager (dnf/apt), pip fails with 'uninstall-no-record-file' because it can't replace the system-tracked copy. The package is present and functional, but the missing marker caused the install to be retried on every service restart. Detect this specific error pattern: if the only pip failure is uninstall-no-record-file, write the .dependencies_installed marker and log a warning instead of returning False, suppressing the repeated warning. Co-Authored-By: Claude Sonnet 4.6 --- src/plugin_system/plugin_loader.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugin_system/plugin_loader.py b/src/plugin_system/plugin_loader.py index 040efa09..cfb51b5a 100644 --- a/src/plugin_system/plugin_loader.py +++ b/src/plugin_system/plugin_loader.py @@ -171,10 +171,24 @@ class PluginLoader: self.logger.info("Dependencies installed successfully for %s", plugin_id) return True else: + stderr = result.stderr or "" + # uninstall-no-record-file means the package is already present at the + # system level (e.g. installed via dnf/apt without a pip RECORD file). + # pip can't replace it, but it IS installed — write the marker so we + # don't retry on every restart. + if "uninstall-no-record-file" in stderr and "error" not in stderr.lower().replace("uninstall-no-record-file", ""): + self.logger.warning( + "Dependencies for %s include system-managed packages (no pip RECORD). " + "Assuming they are satisfied: %s", + plugin_id, stderr.strip() + ) + marker_path.touch() + ensure_file_permissions(marker_path, get_plugin_file_mode()) + return True self.logger.warning( "Dependency installation returned non-zero exit code for %s: %s", plugin_id, - result.stderr + stderr ) return False except subprocess.TimeoutExpired: