RomM version
4.9.0 and later (current master, 66596c8). 4.8.x is not affected.
Describe the bug
Some ROMs are zip files containing several files instead of one. Arcade (MAME/FBNeo) sets are the most common example, but this applies to any platform.
Since 4.9.0 (#3412), RomM hashes these archives by decompressing every file inside and computing one combined "composite" hash over all of them. That was Phase 1 of #3411, whose goal was populating the ROM-level hash fields for archives. Phase 2, deciding which hash each metadata provider should receive during lookup, was explicitly deferred ("this needs separate consideration" in the PR description) and never happened.
The unintended side effect: the metadata handlers for Hasheous and Playmatch read their hashes from the archive's file record, and that value silently changed from "hash of the largest file inside the archive" (pre-4.9.0) to the new composite hash. Both services index a multi-file archive by its largest internal file (the Playmatch developer confirmed the largest-file rule). The composite value matches nothing in their databases, so hash-based identification for multi-file archives silently fails on 4.9.0+. Those ROMs go unmatched or fall back to weaker filename matching.
Verified against the live APIs on 2026-08-07:
- Hasheous: the two MAME sets I tested return HTTP 404 on the composite and resolve on the largest member, to "Aero Fighters" and "Golden Axe: The Revenge of Death Adder" (signatures
MAMEArcade, FBNeo).
- Playmatch: same rule for the datasets it carries, but it does not appear to index MAME sets at all. Both arcade sets return
NoMatch on the composite and on the largest member, so arcade is a Hasheous-only regression. The Playmatch half reproduces on any non-arcade multi-file archive: a No-Intro ROM zipped with a readme returns NoMatch on the composite and gameMatchType='SHA1' on the largest member.
ScreenScraper still works in practice, but not because it matches the composite hash: its lookup endpoint falls back to the filename (romnom) when the hashes miss, and for arcade zips the filename is the set name, which ScreenScraper resolves directly.
Where this happens in the code (permalinks to master at 66596c8):
To Reproduce
- Run RomM 4.9.0+ with Hasheous and/or Playmatch enabled as metadata sources.
- Add a multi-file zip to the library. Any ROM zipped together with a readme reproduces it on both services; a MAME arcade set reproduces it on Hasheous only, for the reason above.
- Scan the platform.
- The ROM gets no hash match, even though the same file matched on 4.8.x.
Expected behavior
Multi-file archives should be identified by Hasheous and Playmatch like they were before 4.9.0.
The fix should not require changing how ROMs are hashed. Since 4.9.0 the scanner already stores per-file hashes for every file inside an archive (archive_members on the file record), so the Hasheous and Playmatch handlers can select the largest member's hashes from there when the file is an archive. That completes Phase 2 of #3411 as originally planned, and works on existing libraries without re-hashing anything. The composite hash should stay as the stored ROM-level identity, which is what #3411 set out to add.
Additional context
Single-file zips are unaffected: the composite hash of one file equals that file's own hash, which is also what the pre-4.9.0 code produced. That is why most non-arcade libraries don't notice, and why this shows up primarily on arcade sets, where multi-file archives are the norm.
RetroAchievements matching is a separate pipeline and is unaffected by this change: for arcade, the RA hash is derived from the zip's filename, and for other platforms RAHasher cannot process multi-file zips at all regardless of what RomM computes.
Related: #3411 (Phase 1), #3412 (implementation).
RomM version
4.9.0 and later (current master, 66596c8). 4.8.x is not affected.
Describe the bug
Some ROMs are zip files containing several files instead of one. Arcade (MAME/FBNeo) sets are the most common example, but this applies to any platform.
Since 4.9.0 (#3412), RomM hashes these archives by decompressing every file inside and computing one combined "composite" hash over all of them. That was Phase 1 of #3411, whose goal was populating the ROM-level hash fields for archives. Phase 2, deciding which hash each metadata provider should receive during lookup, was explicitly deferred ("this needs separate consideration" in the PR description) and never happened.
The unintended side effect: the metadata handlers for Hasheous and Playmatch read their hashes from the archive's file record, and that value silently changed from "hash of the largest file inside the archive" (pre-4.9.0) to the new composite hash. Both services index a multi-file archive by its largest internal file (the Playmatch developer confirmed the largest-file rule). The composite value matches nothing in their databases, so hash-based identification for multi-file archives silently fails on 4.9.0+. Those ROMs go unmatched or fall back to weaker filename matching.
Verified against the live APIs on 2026-08-07:
MAMEArcade,FBNeo).NoMatchon the composite and on the largest member, so arcade is a Hasheous-only regression. The Playmatch half reproduces on any non-arcade multi-file archive: a No-Intro ROM zipped with a readme returnsNoMatchon the composite andgameMatchType='SHA1'on the largest member.ScreenScraper still works in practice, but not because it matches the composite hash: its lookup endpoint falls back to the filename (
romnom) when the hashes miss, and for arcade zips the filename is the set name, which ScreenScraper resolves directly.Where this happens in the code (permalinks to master at 66596c8):
roms_handler.py#L450-L511hasheous_handler.py#L258-L274playmatch_handler.py#L222-L232To Reproduce
Expected behavior
Multi-file archives should be identified by Hasheous and Playmatch like they were before 4.9.0.
The fix should not require changing how ROMs are hashed. Since 4.9.0 the scanner already stores per-file hashes for every file inside an archive (
archive_memberson the file record), so the Hasheous and Playmatch handlers can select the largest member's hashes from there when the file is an archive. That completes Phase 2 of #3411 as originally planned, and works on existing libraries without re-hashing anything. The composite hash should stay as the stored ROM-level identity, which is what #3411 set out to add.Additional context
Single-file zips are unaffected: the composite hash of one file equals that file's own hash, which is also what the pre-4.9.0 code produced. That is why most non-arcade libraries don't notice, and why this shows up primarily on arcade sets, where multi-file archives are the norm.
RetroAchievements matching is a separate pipeline and is unaffected by this change: for arcade, the RA hash is derived from the zip's filename, and for other platforms RAHasher cannot process multi-file zips at all regardless of what RomM computes.
Related: #3411 (Phase 1), #3412 (implementation).