Issue with Python mso_api on Linux machine

System configuration and versions:

Linux xxxxx 6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Python 3.12.3, saleae-mso-api==0.5.4

I’ve stripped this back to basics on the machine I’m having the issue on. Tested also with Logic 2.4.40, that comes up and runs as expected.

from saleae import mso_api

mso = mso_api.MSO()

When stepping thru the steps above in a Python REPL, I get the error shown below.

Traceback (most recent call last):
File “”, line 1, in
File “/usr/local/lib/python3.12/dist-packages/saleae/mso_api/mso_device.py”, line 41, in init
self.wrapper = wrapper or MsoWrapper(serial_number)
^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.12/dist-packages/saleae/mso_api/wrapper.py”, line 138, in init
if proc.name() == get_binary_tool_path().name:
^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.12/dist-packages/saleae/mso_api/wrapper.py”, line 74, in get_binary_tool_path
return ensure_executable_permissions(path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.12/dist-packages/saleae/mso_api/wrapper.py”, line 44, in ensure_executable_permissions
binary_path.chmod(binary_path.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP)
File “/usr/lib/python3.12/pathlib.py”, line 1329, in chmod
os.chmod(self, mode, follow_symlinks=follow_symlinks)
PermissionError: [Errno 1] Operation not permitted: ‘/usr/local/lib/python3.12/dist-packages/saleae/bin/linux-x64/mso_data_recorder’

I went inspected the file referenced, and even made it executable, shown below.

-rwxr-xr-x 1 root root 43517328 Jan 30 00:40 /usr/local/lib/python3.12/dist-packages/saleae/bin/linux-x64/mso_data_recorder

If I run the file directly, I get this:

[2026-02-04 01:10:47.989107] [C] [tid 46173] [main] [saleae_log.cpp:341] Global logging level is set to: info
A subcommand is required
Run with --help for more information.
[2026-02-04 01:10:48.002990] [I] [tid 46175] [usb] [base_usb_manager.cpp:28] SALEAE_IGNORE_DEVICE is set to NullOpt
[2026-02-04 01:10:48.103801] [I] [tid 46173] [usb] [LinuxUsbDevice.cpp:40] Destroying libusb context

I wasn’t expecting anything usable from this file, I presume it’s the backend binary that the library calls.

Suggestions of solutions or what I should poke at to provide more information?

In further testing, I find that I can load the library and create the instance (and see the device’s part number) if I run Python as root.

FWIW, I have the Python MSO library installed as root for global access on the system.

By having set the file as executable while root, and editing /usr/local/lib/python3.12/dist-packages/saleae/mso_api/wrapper.py to not try to twiddle file permissions, I’ve gotten this to load.

Hi @trevor.marvin, sorry for the trouble with this, and I’m glad you were able to find a workaround!

As you have found, the source of the problem here is that the package was owned by a different user than the current user, which caused the chmod operation to fail.

You mentioned this:

FWIW, I have the Python MSO library installed as root for global access on the system.

I wanted to ask - is this a normal workflow? It’s not one I’m familar with.

It looks like we should try to package our binaries with the correct permissions to start with, then update that function to check permissions instead of blindly trying to set the permissions, and then optionally provide a better error message if it still manages to fail.

Installing globally, for me, is a fairly normal workflow. I build these on little computer systems that are dedicated for instrumentation. It partly becomes a protection from the user account modifying binaries.