When saving cover art as separate files, Picard 3 ignores the "front" flag from the Cover Art Archive JSON: an image that carries the type "front" but is not flagged as the front image is treated as a front cover and therefore gets the generic "cover" file name instead of its type-based name.
Steps to reproduce
1. Options > Cover Art: enable "Save cover images as separate files", keep the default file name mask "cover", and enable "Use the primary image type as the file name".
2. Load a release whose CAA data contains an image with types ["Front","Back"] and "front": false, for example https://musicbrainz.org/release/b28a0bec-678f-48ab-a6f1-6ca768cda4b6 (the digipack spread, CAA image 25437782027).
3. Save the album.
Actual (Picard 3.0.1 / 3.0.2)
- cover.jpg for the image flagged front=true
- cover (1).jpg for the digipack spread (types ["Front","Back"], front=false)
Expected
- cover.jpg for the image flagged front=true
- front.jpg for the digipack spread
Picard 2.13.3 produces front.jpg for the equivalent case: release https://musicbrainz.org/release/f2011ed3-d069-4ac1-8b02-190a705ffc57 contains an image with types ["Front"] and "front": false (CAA image 22725028557), and 2.13.3 saved it as front.jpg (see screenshot 1 below).
Analysis
CoverArtImage.is_front_image() gives an explicitly set is_front precedence over the type list: if is_front is not None it is returned as is, otherwise "front" in types decides. For CAA images is_front is taken from the JSON "front" field.
When images are written to files, Picard 3 creates a separate copy for the files target in CoverArtImageProcessing.run_processors_queue() (picard/coverart/processing/init_.py) by calling coverartimage.set_external_file_data(data), and CoverArtImage.save() then prefers that copy whenever external_file_coverart is set.
CoverArtImage.set_external_file_data() (picard/coverart/image.py) constructs the new CoverArtImage with data, url, comment, types, support_types, support_multi_types and id3_type, but not is_front. The copy therefore keeps the class default is_front = None, is_front_image() falls back to "front" in types, and save() uses the "cover" file name mask instead of the type name.
Embedded picture types are not affected because id3_type is passed explicitly; only the file name changes. is_front is also the only piece of image state still missing from the copy: PICARD-3277 fixed the loss of types and comments in this same function, but is_front was not covered.
Proposed fix
Pass is_front=self.is_front in set_external_file_data(), and add a regression test that saves an image with types ["front","back"], front=False and image_type_as_filename=True and asserts the resulting file name is "front".
Impact
After upgrading from 2.13.3, re-running Picard 3 on an already tagged album leaves the old front.jpg in place and creates an additional cover (1).jpg, so duplicate or orphan sidecar files have to be cleaned up manually.
Related
PICARD-3277 (same function, types/comment propagation) and PICARD-701 (front images should use the "cover" file name).
Affected versions
Regression since 3.0.0; reproduced with 3.0.1 and 3.0.2. Picard 2.13.3 behaves as expected.
Attachments
Screenshot 1 - Picard 2.13.3, sidecars written 2026-10-07: the image with types ["Front"] and "front": false is saved as front.jpg.
Screenshot 2 - Picard 3.0.1, sidecars written 2026-10-17: the image with types ["Front","Back"] and "front": false is saved as cover (1).jpg.
Both albums are from the same library and were tagged with the same cover art settings. The Picard 2.13.3 to 3.0.1 upgrade happened on 2026-10-09, i.e. between the two dates shown in the screenshots.