Skip to content

Plugins with conflicting dependency versions can crash each other #1408

Description

@alexmgee

Environment
OS: Windows 11
LFS: v0.5.3 - 55 - g3f850963
GPU: 3090ti

Summary
Each plugin gets its own uv venv, but all plugins run in a single embedded CPython interpreter, and PluginManager._load_module permanently prepends every plugin's venv site-packages to sys.path (src/python/lfs_plugins/manager.py:354-396, as of 3f85096). Because sys.modules is interpreter-wide, the first plugin to import a given package wins for the whole process, so every other plugin silently gets that plugin's copy instead of the one pinned in its own venv. For packages with native extensions, a version mismatch means another plugin's .pyd executes in place of the one the calling plugin was written against. I came to this conclusion after a user named 'heat' shared their problems in the plugin channel on July 7th and I looked into it with Claude/Codex (who also helped me write this issue report).

  • GPU bundle adjustment options fail with AttributeError: ... SparseLinearAlgebraLibraryType' has no attribute 'CUDA_SPARSE', reproduced by running solver-config code against a different plugin's 4.0.2 wheel: 4.0.2's enum has no CUDA_SPARSE. The user's 4.1.0 wheel is fine; it just doesn't get loaded.
  • Selecting Caspar solver crashes the entire application, deterministically: exception 0xc0000005, faulting module _core.cp312-win_amd64.pyd, the faulting module path inside another plugin's venv (colmap_plugin's or densification's, varying by session). The exact native frame is pending the user's crash dump, but the module identity shows a different plugin's native code executing.
  • Relaunching doesn't help: the other plugins import pycolmap at load time, so sys.modules is poisoned at every startup before any pipeline runs.

Any same-named distribution across plugin venvs has this property: torch, opencv, numpy etc. Pure-Python mismatches cause subtle wrong-behavior; native-extension mismatches are the crash class. Plugin authors currently have no way to know their pinned dependency isn't the one running.

Reproduction

  1. Install any two plugins that pin different versions of the same native package (today: colmap_plugin or densification [pycolmap 4.0.2] alongside lichtfeld-360-plugin [pycolmap 4.1.0]).
  2. Launch LichtFeld Studio; run a 360-plugin reconstruction with a GPU BA solver.
  3. Observe the CUDA_SPARSE AttributeError (or worse, depending on code path). In a Python console in-process, sys.modules["pycolmap"].__ file __ points into the other plugin's venv.

Proposal
Before handing control to a plugin, index its installed packages and group them by name. If the same package name shows up in more than one plugin at a different version (or a different build of the same version), that's a conflict. Log a plain warning for pure-Python packages, and an error naming both plugins when the package contains native code (.pyd/.so), since that's the case that crashes. Version strings alone aren't enough because pycolmap 4.1.0 ships as both a cuDSS build and a plain build, both reporting 4.1.0. The check could compare version + the list of native files, not just the version number. This wouldn't solve the issue but could be a helpful diagnostic/alert.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions