Skip to content

Panic in buildDownloads when Files slice is empty (index out of range [0]) #223

@devmapal

Description

@devmapal

Summary

Grout panics when opening the download flow for a game whose cached row has HasMultipleFiles == false and len(Files) == 0. The single-file branch in buildDownloads does g.Files[0] without a length check.

Environment

  • Grout: v4.8.1.1-beta.6 (arm64, ROCKNIX on RK3566 / Anbernic RG DS)
  • RomM server: 4.8.1
  • CFW: ROCKNIX (nightly 20260429)

Steps to reproduce

  1. Have a game in the local SQLite cache whose games.data_json omits a files array (observed after incremental cache updates).
  2. Open game details and start download (or reach the download UI) for that title.
  3. Process exits immediately with a Go panic.

Example

Game: Professor Layton and the Curious Village (Nintendo DS), games.id = 60 in grout.db. Cached data_json includes fs_name, full_path, metadata, etc., but no files key; instr(data_json, 'files') is 0.

Stack trace (excerpt)

panic: runtime error: index out of range [0] with length 0
	panic: sync: negative WaitGroup counter   // secondary, during SDL/gabagool cleanup after first panic

grout/ui.(*DownloadScreen).buildDownloads(...)
	/build/ui/download.go:372 +0x2288
grout/ui.(*DownloadScreen).draw(...)
	/build/ui/download.go:98
grout/ui.(*DownloadScreen).Execute(...)
	/build/ui/download.go:63

Last log line before panic: Using cached artwork for game details for the Layton title.

Expected behavior

No panic: either refuse download with a clear error (“no file metadata; refresh library”), or synthesize a download from fs_name / refetch full ROM from the API when Files is empty.

Suggested fix

In buildDownloads (ui/download.go), guard the non–HasMultipleFiles branch: if len(g.Files) == 0, return a handled error or build the download URL from existing fields (e.g. fs_name) after confirming RomM API contract.

Logs

  • Application JSON log: Grout/logs/app.log
  • Full panic on ROCKNIX also appeared in /var/log/exec.log (port launch stderr).

This bug report was drafted with Cursor (AI-assisted investigation); facts and traces were verified on device.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions