When mise meets system packages: A powerprofilesctl debugging saga

#python#mise#linux#debugging#sway#power-management

The Error That Started It All

$ powerprofilesctl get
Traceback (most recent call last):
  File "/usr/bin/powerprofilesctl", line 8, in <module>
    from gi.repository import Gio, GLib
ModuleNotFoundError: No module named 'gi'

Fresh off optimizing my Sway configuration for laptop power management, I hit this wall. The power-profiles-daemon was installed, the service was running, but the CLI tool was completely broken.

The mise Factor

Here’s where it gets interesting. I use mise to manage my development environments:

$ mise current
node 24.6.0
python 3.13.7 This is the problem child
ruby 3.4.5
# ... other tools
$ which python3
/home/seuros/.local/share/mise/installs/python/3.13.7/bin/python3

Mise creates isolated environments for each tool. Great for development, but it can cause unexpected conflicts with system integration.

The Diagnosis Dance

Let’s trace what’s happening:

# Check if gi module works with mise Python
$ ~/.local/share/mise/installs/python/3.13.7/bin/python3 -c "import gi; print('gi module found')"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import gi; print('gi module found')
    ^^^^^^^^^
ModuleNotFoundError: No module named 'gi'

# Check with system Python
$ /usr/bin/python3 -c "import gi; print('gi module found')"
gi module found

Bingo! The gobject-introspection library (python-gobject package) is installed for the system Python, not the mise-managed one.

The Shebang Showdown

Here’s the culprit:

$ head -1 /usr/bin/powerprofilesctl
#!/usr/bin/env python3

That innocent-looking shebang resolves to whatever python3 is in your PATH. With mise active, that’s:

But if we force it to use the system Python:

The One-Line Fix

# Backup first (always)
$ sudo cp /usr/bin/powerprofilesctl /usr/bin/powerprofilesctl.orig

# Fix the shebang
$ sudo sed -i '1s|#!/usr/bin/env python3|#!/usr/bin/python3|' /usr/bin/powerprofilesctl

# Test the fix
$ powerprofilesctl get
balanced

$ powerprofilesctl list
  performance:
    CpuDriver: intel_pstate
    Degraded: no

* balanced:
    CpuDriver: intel_pstate
    PlatformDriver: placeholder

  power-saver:
    CpuDriver: intel_pstate
    PlatformDriver: placeholder

Perfect! Now my Sway power management works flawlessly:

The Broader Lesson

This is a classic case of modern tooling vs. system integration. Tools like mise, pyenv, nvm, and rbenv create isolated environments that can break system scripts expecting global interpreters.

The fix patterns:

  1. For scripts you control: Use virtual environments properly
  2. For system scripts: Force absolute paths to system interpreters
  3. For development: Be aware of which environment you’re in

Prevention Tips

# Check what your environment resolves to
$ which python3
$ /usr/bin/env python3 --version vs /usr/bin/python3 --version

# For system packages that include Python scripts,
# consider if they need system Python specifically
$ pacman -Ql power-profiles-daemon | grep bin/

Sometimes the simplest bugs have the most educational value. A single character change (env removal) solved hours of head-scratching and taught me about the subtle ways development tools can interfere with system integration.

Aftermath

My Sway setup now dynamically adjusts performance based on power state, all thanks to fixing this Python environment conflict. The lesson? When mise meets system packages, shebangs matter.

# This now works perfectly
$ powerprofilesctl set power-saver && echo "Battery mode activated"
$ powerprofilesctl set performance && echo "Plugged in, full power"

The fix is deployed, the laptop is optimized, and I learned something new about Python environment isolation. Not bad for a debugging session.