Bug: Deduplication doesnt catch when unknown attribute is used for tie
- Dominant language
- Python
- Stars
- 15.7k
- Forks
- 2.1k
- Avg merge
- 4d 21h
- Merged PRs (30d)
- 31
Description
### Problem
Running this command in verbose (`-vv`) mode:
```sh
root@beets:~ # beet -vv --plugins=duplicates dup "/media/music/Abe Duque/So Underground It Hurts/"
user configuration: /root/.config/beets/config.yaml
data directory: /root/.config/beets
plugin paths: []
Loading plugins: duplicates
Sending event: pluginload
library database: /root/.config/beets/library.db
library directory: /media/music
Sending event: library_opened
Parsed query: AndQuery([PathQuery('path', b'/media/music/Abe Duque/So Underground It Hurts', fast=True, case_sensitive=True)])
Parsed sort: NullSort()
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/01 Cooly Kat.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/01 Cooly Kat.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/01 Cooly Kat.2.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/02 What You Gonna Do.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/02 What You Gonna Do.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/03 Slaves.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/03 Slaves.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/04 Give It To Her Good.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/04 Give It To Her Good.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/05 Love To Ya.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/05 Love To Ya.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/06 Miracle To Fill My Life.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/06 Miracle To Fill My Life.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/07 Acid Featuring Blake Baxter.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/07 Acid Featuring Blake Baxter.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/08 King.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/08 King.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/09 Dream Desires.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/09 Dream Desires.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/10 Ban.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/10 Ban.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/11 Champagne.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/11 Champagne.1.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/12 After Hour Jesus Revealed.mp3 cached:not computing checksum
duplicates: key ffmpeg on item /media/music/Abe Duque/So Underground It Hurts/12 After Hour Jesus Revealed.1.mp3 cached:not computing checksum
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/beets/library/models.py", line 837, in __getitem__
return super().__getitem__(key)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/beets/dbcore/db.py", line 481, in __getitem__
return self._get(key, raise_=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/beets/dbcore/db.py", line 471, in _get
raise KeyError(key)
KeyError: 'lossless'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/beets/dbcore/db.py", line 570, in __getattr__
return self[key]
~~~~^^^^^
File "/usr/local/lib/python3.11/site-packages/beets/library/models.py", line 840, in __getitem__
return self._cached_album[key]
~~~~~~~~~~~~~~~~~~^^^^^
File "/usr/local/lib/python3.11/site-packages/beets/dbcore/db.py", line 481, in __getitem__
return self._get(key, raise_=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/beets/dbcore/db.py", line 471, in _get
raise KeyError(key)
KeyError: 'lossless'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/bin/beet", line 8, in
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.11/site-packages/beets/ui/__init__.py", line 1713, in main
_raw_main(args)
File "/usr/local/lib/python3.11/site-packages/beets/ui/__init__.py", line 1692, in _raw_main
subcommand.func(lib, suboptions, subargs)
File "/usr/local/lib/python3.11/site-packages/beetsplug/duplicates.py", line 192, in _dup
for obj_id, obj_count, objs in self._duplicates(
File "/usr/local/lib/python3.11/site-packages/beetsplug/duplicates.py", line 408, in _duplicates
objs = self._order(objs, tiebreak)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/beetsplug/duplicates.py", line 343, in _order
return sorted(objs, key=key, reverse=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/beetsplug/duplicates.py", line 322, in key
return tuple(getattr(x, k) for k in tiebreak[kind])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/beetsplug/duplicates.py", line 322, in
return tuple(getattr(x, k) for k in tiebreak[kind])
^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/beets/dbcore/db.py", line 572, in __getattr__
raise AttributeError(f"no such field {key!r}")
AttributeError: no such field 'lossless'
```
Led to this problem:
```
duplication didnt succeed
```
### Setup
```
root@beets:~ # beets version
beets version 2.5.1
Python version 3.11.13
plugins: convert, duplicates, embedart, fetchart, info, scrub, web
```
My configuration (output of `beet config`) is:
```yaml
directory: /media/music
library: ~/.config/beets/library.db
logging:
level: DEBUG
# ------------------------------------------------------------------
import:
move: yes # relocate files into /media/music
copy: no
autotag: yes
assume_album: yes
singletons: yes
none_rec_action: asis
duplicate_action: merge
incremental: yes
incremental_skip_later: yes
write: yes
languages: [en]
auto: yes
acoustid:
apikey: ...
match:
strong_rec_thresh: 0.30 # a bit stricter than default
medium_rec_thresh: 0.10
preferred:
countries: ['US', 'GB|UK', 'DE']
media: ['CD', 'Digital Media|File']
original_year: yes
# ------------------------------------------------------------------
paths: # tidy, deterministic layout
default: $albumartist/$album%aunique{}/$track $title
comp: Compilations/$album/$track $title
singleton: Non-Album/$artist/$title
albumtype_soundtrack: Soundtracks/$album/$track $title
# ------------------------------------------------------------------
plugins: [
info,
duplicates,
convert,
web,
fetchart, # optional quality-of-life extras
embedart,
scrub,
]
# --- duplicates configuration ---
duplicates:
strict: true
# authoritative grouping order
keys:
- checksum # exact decoded audio match
- acoustid_id # same recording, different releases
- mb_albumid # exact album duplicate
- artist
- album
- title
# content-based fingerprint
checksum: "ffmpeg -v error -i {file} -map 0:a -f crc -"
# never auto-delete
delete: false
move: /media/music/_duplicates
full: true
path: true
# deterministic best-version selection
tiebreak:
items:
- lossless # True > False
- bits_per_sample # 32 > 24 > 16
- samplerate # 192k > 96k > 48k > 44.1k
- bitrate # higher kbps
- added # earliest import wins last
info:
fields:
- title
- artist
- album
- albumartist
- track
- length
- bitrate
- samplerate
- bits_per_sample
- format
- lossless
- added
- path
- mb_trackid
- mb_albumid
- acoustid_id
- checksum
- ffmpeg
convert:
auto: yes
format: flac
threads: 2
keep_original: no
never_convert_lossy_files: yes
copy_album_art: yes
command: ffmpeg -i "$source" -y -vn -acodec flac "$dest"
replaygain:
backend: ffmpeg # or loudgain / bs1770gain if you prefer
auto: yes
overwrite: no
per_disc: no
targetlevel: 89
threads: 2
web:
host: 0.0.0.0
port: 8337
# ------------------------------------------------------------------
```
Contributor guide
Assessment
This issue has not been assessed yet.