Skip to content

[Bug] Symlinks stopped working on scan #2114

@IvanMazzoli

Description

@IvanMazzoli

RomM version
4.0.0

Describe the bug
I have setup romm as follows:
/docker/romm is my main folder;
/docker/romm/library/roms contains symlink to the various games;
/storage/Games is where the games are actually stored.
(If useful /docker is in sda and /storage is in /sdb)

I have had this configuration for months but it appears that it doesn't work anymore in the scan section, if I try to load a ROM in one of these paths it does without errors.

One of the error i get is "Scan failed: '/storage/Games/GameBoy Advance' is not in the subpath of '/romm/library'"

To Reproduce
Setup romm as I did and try to scan the library

Expected behavior
It should work as it did in older versions

Desktop :

  • OS: [Windows 11]
  • Browser [chrome]
  • Version [138.0.7204.158]

Additional context

Log output:

romm     | INFO:          [RomM][scan][2025-07-21 11:14:54] 🔎 Scanning
romm     | INFO:          [RomM][worker][2025-07-21 11:14:55] high: endpoints.sockets.scan.scan_platforms([], <ScanType.QUICK: 'quick'>, [], ['igdb', 'moby', 'sgdb']) (c43eb759-874c-497f-8aca-d9990cfaf632)
romm     | INFO:          [RomM][scan][2025-07-21 11:14:55] Found 8 platforms in the file system
romm     | INFO:          [RomM][scan][2025-07-21 11:14:55] Folder gba[gba] identified as Game Boy Advance 🎮
romm     | WARNING:  [RomM][scan][2025-07-21 11:14:55] ⚠️  No firmware found for Game Boy Advance[gba]
romm     | ERROR:         [RomM][scan][2025-07-21 11:14:55] Error in scan_platform: '/storage/Games/GameBoy Advance' is not in the subpath of '/romm/library'
romm     | ERROR:         [RomM][worker][2025-07-21 11:14:55] [Job c43eb759-874c-497f-8aca-d9990cfaf632]: exception raised while executing (endpoints.sockets.scan.scan_platforms)
romm     | Traceback (most recent call last):
romm     |   File "/src/.venv/lib/python3.13/site-packages/rq/worker.py", line 1643, in perform_job
romm     |     return_value = job.perform()
romm     |   File "/src/.venv/lib/python3.13/site-packages/rq/job.py", line 1359, in perform
romm     |     self._result = self._execute()
romm     |                    ~~~~~~~~~~~~~^^
romm     |   File "/src/.venv/lib/python3.13/site-packages/rq/job.py", line 1396, in _execute
romm     |     coro_result = loop.run_until_complete(result)
romm     |   File "/usr/local/lib/python3.13/asyncio/base_events.py", line 725, in run_until_complete
romm     |     return future.result()
romm     |            ~~~~~~~~~~~~~^^
romm     |   File "/usr/local/lib/python3.13/contextlib.py", line 101, in inner
romm     |     return await func(*args, **kwds)
romm     |            ^^^^^^^^^^^^^^^^^^^^^^^^^
romm     |   File "/backend/endpoints/sockets/scan.py", line 517, in scan_platforms
romm     |     raise e
romm     |   File "/backend/endpoints/sockets/scan.py", line 492, in scan_platforms
romm     |     scan_stats += await _identify_platform(
romm     |                   ^^^^^^^^^^^^^^^^^^^^^^^^^
romm-db  | 2025-07-21 11:14:55 12 [Warning] Aborted connection 12 to db: 'romm' user: 'romm-user' host: '172.18.0.22' (Got an error reading communication packets)
romm     |     ...<6 lines>...
romm     |     )
romm     |     ^
romm     |   File "/backend/endpoints/sockets/scan.py", line 381, in _identify_platform
romm     |     fs_roms = await fs_rom_handler.get_roms(platform)
romm     |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
romm     |   File "/backend/handler/filesystem/roms_handler.py", line 549, in get_roms
romm     |     fs_single_roms = await self.list_files(path=rel_roms_path)
romm     |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
romm     |   File "/backend/handler/filesystem/base_handler.py", line 485, in list_files
romm     |     full_path = self.validate_path(path)
romm     |   File "/backend/handler/filesystem/base_handler.py", line 144, in validate_path
romm     |     full_path.relative_to(base_path_obj)
romm     |     ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
romm     |   File "/usr/local/lib/python3.13/pathlib/_local.py", line 385, in relative_to
romm     |     raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}")
romm     | ValueError: '/storage/Games/GameBoy Advance' is not in the subpath of '/romm/library'
romm     |
romm     | INFO:     [RomM][nginx][2025-07-21 11:14:55] 172.18.0.29 | 85.32.208.146 | GET /ws/socket.io/?EIO=4&transport=websocket 101 | 285 | Chrome Windows | 9.640
romm     | INFO:          [RomM][server][2025-07-21 11:14:55] connection closed

My Docker compose:

version: "3"

volumes:
  mysql_data:
  romm_resources:
  romm_redis_data:

services:
  romm:
    image: rommapp/romm:latest
    container_name: romm
    restart: unless-stopped
    environment:
      - DB_HOST=romm-db
      - DB_NAME=romm
      - DB_USER=romm-user
      - DB_PASSWD=REDACTED
      - ROMM_AUTH_SECRET_KEY=REDACTED
      - IGDB_CLIENT_ID=REDACTED
      - IGDB_CLIENT_SECRET=REDACTED
      - MOBYGAMES_API_KEY=REDACTED
      - STEAMGRIDDB_API_KEY=REDACTED
      - SCREENSCRAPER_USER=REDACTED
      - SCREENSCRAPER_PASSWORD=REDACTED
    volumes:
      - ./resources:/romm/resources # Resources fetched from IGDB (covers, screenshots, etc.)
      - ./redis_data:/redis-data # Cached data for background tasks
      - ./library:/romm/library # Your game library. Check https://github.com/rommapp/romm?tab=readme-ov-file#folder-structure for more details.
      - ./assets:/romm/assets # Uploaded saves, states, etc.
      - ./config:/romm/config # Path where config.yml is stored
      - /storage/Games:/storage/Games # fix symlink
    ports:
      - 5678:8080
    depends_on:
      romm-db:
        condition: service_healthy
        restart: true
    networks:
      - proxy

  romm-db:
    image: mariadb:latest
    container_name: romm-db
    restart: unless-stopped
    environment:
      - MARIADB_ROOT_PASSWORD=REDACTED
      - MARIADB_DATABASE=romm
      - MARIADB_USER=romm-user
      - MARIADB_PASSWORD=REDACTED
    volumes:
      - ./mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      start_period: 30s
      start_interval: 10s
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - proxy

networks:
  proxy:
    external: true

ls -l command output:

dreadtank27@homelab:/docker/romm/library/roms$ ls -l
total 0
lrwxrwxrwx 1 dreadtank27 dreadtank27 31 Apr 16 22:06 gba -> '/storage/Games/GameBoy Advance/'
lrwxrwxrwx 1 dreadtank27 dreadtank27 40 Apr 16 22:11 genesis-slash-megadrive -> '/storage/Games/SEGA Genesis & Megadrive/'
lrwxrwxrwx 1 dreadtank27 dreadtank27 27 Apr 16 22:13 nds -> '/storage/Games/Nintendo DS/'
lrwxrwxrwx 1 dreadtank27 dreadtank27 45 Apr 16 22:10 nes -> '/storage/Games/Nintendo Entertainment System/'
lrwxrwxrwx 1 dreadtank27 dreadtank27 27 Jul 15 22:04 ps -> /storage/Games/Playstation/
lrwxrwxrwx 1 dreadtank27 dreadtank27 30 Apr 16 22:08 switch -> '/storage/Games/Nintendo Switch'
lrwxrwxrwx 1 dreadtank27 dreadtank27 28 Apr 16 22:12 wii -> '/storage/Games/Nintendo Wii/'
lrwxrwxrwx 1 dreadtank27 dreadtank27 20 Jul 20 20:53 xbox -> /storage/Games/Xbox/

dreadtank27@homelab:/storage/Games$ ls -l
total 32
drwxrwxrwx 2 dreadtank27 dreadtank27 4096 Jul 11 13:50 'GameBoy Advance'
drwxrwxrwx 2 dreadtank27 dreadtank27 4096 Apr 16 22:12 'Nintendo DS'
drwxrwxrwx 2 dreadtank27 dreadtank27 4096 Jul 21 12:56 'Nintendo Entertainment System'
drwxrwxrwx 6 dreadtank27 dreadtank27 4096 May 16 23:59 'Nintendo Switch'
drwxrwxrwx 2 dreadtank27 dreadtank27 4096 Apr 16 22:12 'Nintendo Wii'
drwxrwxrwx 3 dreadtank27 dreadtank27 4096 Jul 15 22:01  Playstation
drwxrwxrwx 2 dreadtank27 dreadtank27 4096 Apr 16 22:10 'SEGA Genesis & Megadrive'
drwxrwxrwx 2 dreadtank27 dreadtank27 4096 Jul 20 20:47  Xbox

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions