beets
beets copied to clipboard
Multiple plugin paths is not working
Problem
Documentation states that multiple plugin paths can be defined (https://beets.readthedocs.io/en/stable/reference/config.html#plugins - plugin path subheader). The documentation states the format should be:
pluginpath:
- /path/one
- /path/two
Use of the dashes causes a yaml error. This may be an error in the document. Removing the dashes allows the format to be accepted, however, the two paths do not seem to be used. I created a separate directory for a custom plugin that I developed for my own use. I want to keep it separate from the main body of beets.
Using the pluginpath configuration does not seem to be recognized by beets at all. I tested:
- having the first path point to the default plugin directory (.../beetsplug) and having a second pluginpath pointing to my custom plugin directory
- switching the order of the two directories so that the custom directory was first
- putting in a non-existent directory as the sole pluginpath
In all cases delivered plugins were found (e.g. the delivered beetsplug directory was referenced) and the custom plugin was not. It appears that other than confirming that the yaml is formatted, the pluginpath is not referenced at all.
Setup
- OS: MacOS Sequoia 15.5
- Python version: 3.12.2
- beets version: 2.3.1
- Turning off plugins made problem go away (yes/no): no
My configuration (output of beet config) is:
beet config
directory: /Volumes/share/music
# --------------- Main ---------------
library: /Volumes/share/beets/library1.db
import:
copy: no
move: yes
write: yes
log: /Volumes/share/beets/import.log
singletons: no
asciify_paths: yes
bell: yes
incremental: no
incremental_skip_later: yes
resume: yes
paths:
default: Albums/$albumartist/$album%aunique{}/$disc-$track $artist - $title
singleton: Non-Album/$artist ($year) - $title
comp: Compilations/$album%aunique{}/$disc-$track $artist - $title
albumtype_soundtrack: Soundtracks/$album/$disc-$track $artist - $title
pluginpath: /Users/myname/ownCloud/GitHub/beets/src/beets/beetsplug /Users/myname/ownCloud/GitHub/beets/custom/beetsplug
replace:
'[\\/]': _
^\.: _
'[\x00-\x1f]': _
'[<>:"\?\*\|]': _
\.$: _
\s+$: ''
^\s+: ''
^-: _
match:
strong_rec_thresh: 0.2
max_rec:
missing_tracks: low
unmatched_tracks: low
preferred:
countries: [US, GB|UK]
original_year: yes
musicbrainz:
genre: no
# --------------- Plugins ---------------
plugins: fetchart
plugfiles:
mode: stage
format: $albumartist - $title
temp_dir: /Volumes/share/tempmusic
scrub:
auto: yes
embedart:
compare_threshold: 0
fetchart:
cover_names: front art album folder
sources: filesystem coverart amazon albumart
auto: yes
minwidth: 0
maxwidth: 0
quality: 0
max_filesize: 0
enforce_ratio: no
cautious: no
store_source: no
high_resolution: no
deinterlace: no
cover_format:
google_key: REDACTED
google_engine: REDACTED
fanarttv_key: REDACTED
lastfm_key: REDACTED
lyrics:
auto: yes
google_API_key: REDACTED
google_engine_ID: REDACTED
sources: google musixmatch genius tekstowo
lastgenre:
auto: yes
canonical: no
count: 3
fallback: none
force: yes
min_weight: 10
prefer_specific: no
source: album
whitelist: yes
title_case: yes
replaygain:
auto: yes
backend: ffmpeg
per_disc: no
convert:
auto: no
copy_album_art: yes
embed: yes
never_convert_lossy_files: yes
delete_originals: yes
missing:
# --------------- Search ---------------
format_item: $album - $disc-$track $title
count: no
total: no
Hi, thank you for the report!
That is a good find. I just checked the relevant code and in theory we do resolve the pluginpath config option as string sequence.
Something like
pluginpath: [./path1, ./path2]
should work. That said, there is no test inplace for multiple plugin paths, so something could indeed be broken. Could you try again using the inline array syntax? I don't see why you original approach should not not work tho.
Thanks for your assistance on this. I did a test. I moved the configuration to inline and it did not work in that format either. Let me know if I can do anything else to assist.
Bill
On Jun 19, 2025, at 4:16β―AM, Sebastian Mohr @.***> wrote:
semohr left a comment (beetbox/beets#5825) https://github.com/beetbox/beets/issues/5825#issuecomment-2987358511 Hi, thank you for the report!
That is a good find. I just checked the relevant code https://github.com/beetbox/beets/blob/8fd20b9b6774509c7f1846d2cf3b3e56acea03ea/beets/ui/__init__.py#L1634 and in theory we do resolve the pluginpath config option as string sequence.
Something like
pluginpath: [./path1, ./path2] should work. That said, there is no test inplace for multiple plugin paths, so something could indeed be broken. Could you try again using the inline array syntax? I don't see why you original approach should not not work tho.
β Reply to this email directly, view it on GitHub https://github.com/beetbox/beets/issues/5825#issuecomment-2987358511, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFGESX34ULK65VRT6FZGQL3EJ5XPAVCNFSM6AAAAAB7OM5QQ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDSOBXGM2TQNJRGE. You are receiving this because you authored the thread.
What was the yaml error in the first place? I have pluginpath in my config which works.
The issue is about multiple pluginpaths. E.g. adding a folder with your own plugins. As mentioned above:
In all cases delivered plugins were found (e.g. the delivered beetsplug directory was referenced) and the custom plugin was not. It appears that other than confirming that the yaml is formatted, the pluginpath is not referenced at all.
There is no specific error raised sadly π
The only yaml error occurs if you follow the format listed in the documentation (i.e. putting a hyphen in front of the value). I think that is just a documentation error. This is noted above.
The more important issue is that adding an additional plug in path value does not appear to be recognized. No error is generated, the program just appears to ignore the directive.
Bill Cage (205) 422-6081
On Fri, Jun 20, 2025, 4:07β―AM Sebastian Mohr @.***> wrote:
semohr left a comment (beetbox/beets#5825) https://github.com/beetbox/beets/issues/5825#issuecomment-2990382443
The issue is about multiple pluginpaths. E.g. adding a folder with your own plugins. As mentioned above:
In all cases delivered plugins were found (e.g. the delivered beetsplug directory was referenced) and the custom plugin was not. It appears that other than confirming that the yaml is formatted, the pluginpath is not referenced at all.
There is no specific error sadly π
β Reply to this email directly, view it on GitHub https://github.com/beetbox/beets/issues/5825#issuecomment-2990382443, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFGESVB3WBI4AJIGGAISWL3EPFLNAVCNFSM6AAAAAB7OM5QQ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDSOJQGM4DENBUGM . You are receiving this because you authored the thread.Message ID: @.***>
Okay. @wcage03 says there is a error, @semohr says there isn't. Since @wcage03 is the OP, I guess that they saw the error and I'm curious what that error is.
As said, I have pluginpath in my config with multiple paths with hyphens in front of them and that works.
beet config converts that into a string list, so that's also a possible way to use it (as stated earlier in the thread).
But, what I see in the config in OP's initial post, I see a syntax where I don't have much faith of it working.
for reference, in my config:
pluginpath:
- ~/.local/share/pipx/venvs/beets-xtractor/lib/python3.13/site-packages/beetsplug/
- ~/.local/share/venv/lib/python3.13/site-packages/beetsplug/
- ~/gitzooi/whatlastgenre/plugin/beets/beetsplug
beet config output:
pluginpath: [~/.local/share/pipx/venvs/beets-xtractor/lib/python3.13/site-packages/beetsplug/, ~/.local/share/venv/lib/python3.13/site-packages/beetsplug/, ~/gitzooi/whatlastgenre/plugin/beets/beetsplug]
It would probably be useful to see the verbose log (beet -vv ...) of any command that fails to use pluginpath.
Also, as far as I can tell, you will still need to enable those plugins, which you don't seem to do:
plugins: fetchart # <- no custom plugins enabled here
This is actually pretty simple for me to recreate. I installed a clean latest version of beets in an "editable" configuration using the command below (as documented). pip install -e git+https://github.com/beetbox/beets#egg=beets
No mods, no adds, nothing but delivered code. I have one custom plugin that I developed. I usually stick it in the source directory beetsplug where all the delivered plugins live. It works fine for my purposes. I noticed in the documentation that you can specify multiple plugin paths. This is attractive so that I can keep my custom code separate. I gave it a shot. As noted in the original post, I used the format:
pluginpath:
- /Users/myname/ownCloud/GitHub/beets/src/beets/beetsplug
- /Users/myname/ownCloud/GitHub/beets/custom/beetsplug
As documented (with the preceding hyphens). The first is the path to the delivered plugins and the second is a path to my custom code. When I use the hyphens, I get this error when I run the command "beet version":
beet version
configuration error: paths.pluginpath: must be a string
When I remove the hyphens, I get a normal response from beet version, e.g.
beet version
beets version 2.3.1
Python version 3.12.2
plugins: badfiles, convert, embedart, fetchart, info, lastgenre, lyrics, mbsync, missing, musicbrainz, replaygain, scrub, unimported
Note: the specific plugins that are included is irrelevant and does not impact the outcome of the test. Without an error, I assume at this point that Beets is configured to look at my pluginpath(s) now. Adding my custom plugin to the plugins: line in the config, I get the following when I run beet version:
beet version
** error loading plugin plugfiles:
Traceback (most recent call last):
File "/Users/myname/ownCloud/GitHub/beets/src/beets/beets/plugins.py", line 361, in load_plugins
namespace = __import__(modname, None, None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named 'beetsplug.plugfiles'
Note: my custom plugin is named plugfiles. If I copy my custom plugin into the source beetsplug directory, then everything works (my custom plugin is found and executes as expected). Clearly, it is not looking in my custom plugin path. For completeness, I ran an ls command on the custom path to make sure that I did not make a typo on the path definition:
ls /Users/myname/ownCloud/GitHub/beets/custom/beetsplug
plugfiles.py
My plugin is where I tried to tell beets to look. I very well could be doing something wrong, but the test case that I am using seems to be simple and straight to a demonstration of the intended functionality. That said, I am not going to lose sleep over this since all I have to do is copy my custom plugin into the delivered directory and I am golden, but it appears to be an error in the code and/or an error in the documentation. Happy to help in anyway that I can.
I just tried to reproduce this and I failed to do so. I'm loading plugins from different folders without any issue
Here my config (notice the myawesomeplugin line)
# config.yaml
...
plugins:
[
info,
the,
fetchart,
embedart,
ftintitle,
lastgenre,
missing,
albumtypes,
scrub,
zero,
mbsync,
duplicates,
convert,
fromfilename,
importfeeds,
inline,
edit,
spotify,
plexupdate,
myawesomeplugin
]
pluginpath:
- /mnt/Repositories/test/beetsplug
- /mnt/Repositories/beets/beetsplug
...
The plugin looks as follows:
from beets.plugins import BeetsPlugin
def loaded():
print("My plugin loaded!")
class MyPlugin(BeetsPlugin):
def __init__(self):
super().__init__()
self.register_listener("pluginload", loaded)
beet version gives the following output showing the plugin was loaded successfully:
My plugin loaded!
beets version 2.3.1
Python version 3.12.11
plugins: albumtypes, convert, duplicates, edit, embedart, fetchart, fromfilename, ftintitle, importfeeds, info, inline, lastgenre, mbsync, missing, myawesomeplugin, plexupdate, scrub, spotify, the, zero
@wcage03 Maybe your plugin is malformed?
The plugin works perfectly fine when it is in the main folder so there is no problem with the plugin itself. It is just not found for me via the plluginpath directive. The only possible issue would be dependencies within the plugin where it relies on other existing plugin code. I doubt this is the problem and logically it would not make sense that any existing dependencies would have to be replicated into the secondary path.
Since I am doing a complete clean install (as described in my post) could it be a path directive or other python directive that is solving the path issue for you and it is not actually being picked up from the pluginpath directive? It would be interesting to see if you removed your βtestβ path from your config and testing to see if your install continues to find your plugin.
As I said previously, this was something that I noted and I can replicate on my machine so I posted an issue. It does not cause me great heartburn since I can just copy my single custom plugin to the folder.
I do appreciate your persistence in following up on this.
On Jun 26, 2025, at 5:55β―AM, Sebastian Mohr @.***> wrote:
semohr left a comment (beetbox/beets#5825) https://github.com/beetbox/beets/issues/5825#issuecomment-3008066491 I just tried to reproduce this and I failed to do so. I'm loading plugins from different folders without any issue Here my config (notice the myawesomeplugin line)
config.yaml
... plugins: [ info, the, fetchart, embedart, ftintitle, lastgenre, missing, albumtypes, scrub, zero, mbsync, duplicates, convert, fromfilename, importfeeds, inline, edit, spotify, plexupdate, myawesomeplugin ]
pluginpath: - /mnt/Repositories/test/beetsplug - /mnt/Repositories/beets/beetsplug ... The plugin looks as follows:
from beets.plugins import BeetsPlugin
def loaded(): print("My plugin loaded!")
class MyPlugin(BeetsPlugin): def init(self): super().init() self.register_listener("pluginload", loaded) beet version gives the following output showing the plugin was loaded successfully:
My plugin loaded! beets version 2.3.1 Python version 3.12.11 plugins: albumtypes, convert, duplicates, edit, embedart, fetchart, fromfilename, ftintitle, importfeeds, info, inline, lastgenre, mbsync, missing, myawesomeplugin, plexupdate, scrub, spotify, the, zero @wcage03 https://github.com/wcage03 Maybe your plugin is malformed?
β Reply to this email directly, view it on GitHub https://github.com/beetbox/beets/issues/5825#issuecomment-3008066491, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFGESUPKZPPRWA3WGLQ7T33FPGQNAVCNFSM6AAAAAB7OM5QQ2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTAMBYGA3DMNBZGE. You are receiving this because you were mentioned.
If I remove the test pluginpath the plugin is not found anymore (as expected). For me everything seems to be in order π€
** error loading plugin myawesomeplugin:
Traceback (most recent call last):
File "/mnt/Repositories/confuse/src/beets/beets/plugins.py", line 361, in load_plugins
namespace = __import__(modname, None, None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named 'beetsplug.myawesomeplugin'
beets version 2.3.1
Python version 3.12.11
plugins: albumtypes, convert, duplicates, edit, embedart, fetchart, fromfilename, ftintitle, importfeeds, info, inline, lastgenre, mbsync, missing, plexupdate, scrub, spotify, the, zero
As I said previously, this was something that I noted and I can replicate on my machine so I posted an issue. It does not cause me great heartburn since I can just copy my single custom plugin to the folder.
Would be nice if I could replicate it too tho, otherwise I'm not really able to fix it π