"File Missing" Error in Sandbox Only

First, here’s the core of my manifest showing everything the flatpak should have access to:

id: io.github.evilsupahfly.amulet_flatpak
runtime: org.freedesktop.Platform
runtime-version: '24.08'
sdk: org.freedesktop.Sdk
command: amulet_map_editor

finish-args:
  - --device=all
  - --device=dri
  - --allow=devel
  - --allow=per-app-dev-shm
  - --share=network
  - --share=ipc
  - --socket=fallback-x11
  - --socket=wayland
  - --filesystem=host
  - --filesystem=host-os
  - --filesystem=home
  - --filesystem=/tmp
  - --filesystem=xdg-config/AmuletMapEditor:create
  - --filesystem=xdg-cache/AmuletMapEditor:create
  - --filesystem=xdg-run/gvfs
  - --filesystem=xdg-run/gvfsd
  - --talk-name=org.freedesktop.Notifications
  - --env=LIBGL_ALWAYS_SOFTWARE="0"
  - --env=OPENGL_VERSION=3.3
  - --env=OPENGL_LIB=/usr/lib/x86_64-linux-gnu/libGL.so
  - --env=PS1=[ AMULET_FLATPAK > \w ] >
  - --env=PYTHONPATH=/app/lib/python3.12
# Uncomment the following options to increase debug output verbosity in the terminal
#  - --env=PYTHONDEBUG=3
#  - --env=PYTHONVERBOSE=3
#  - --env=PYTHONTRACEMALLOC=10
#  - --env=G_MESSAGES_DEBUG=all

modules:
  - shared-modules/libjpeg8/libjpeg8.json
  - shared-modules/glew/glew.json
  - shared-modules/glu/glu-9.json
  - pip-gen.yaml
  - flatpak-debug-build.yaml
  - name: metainfo-xml
    buildsystem: simple
    build-commands:
      - install -Dm644 io.github.evilsupahfly.amulet_flatpak.metainfo.xml -t ${FLATPAK_DEST}/share/metainfo/
    sources:
      - type: file
        path: io.github.evilsupahfly.amulet_flatpak.metainfo.xml
  - name: metainfo-desktop
    buildsystem: simple
    build-commands:
      - install -Dm755 io.github.evilsupahfly.amulet_flatpak.desktop -t ${FLATPAK_DEST}/share/applications/
    sources:
      - type: file
        path: io.github.evilsupahfly.amulet_flatpak.desktop
  - name: metainfo-ico
    buildsystem: simple
    build-commands:
      - install -Dm644 io.github.evilsupahfly.amulet_flatpak.png -t ${FLATPAK_DEST}/share/icons/hicolor/256x256/apps/
    sources:
      - type: file
        path: io.github.evilsupahfly.amulet_flatpak.png
  - name: amulet-debug
    buildsystem: simple
    build-commands:
      - install -Dm555 debug.sh -t ${FLATPAK_DEST}/bin/
    sources:
      - type: file
        path: debug.sh

In theory, this should give me unfettered (or as close as possible) access to HOME and the XDG folders. Now, here’s the background. I am (still) attempting to turn the Python-built Amulet Map Editor into a Flatpak app, but I’m encountering issues with bundled files. When I install Amulet into a Python VENV, it works fine. But when I run the flatpak, I get errors:

2025-09-01 19:11:37.261 | DEBUG    | resource_pack_manager.py:247 | get_texture_path() | [PROBE:TEXTURE] Called with ns=minecraft, rel=block/water
2025-09-01 19:11:37.261 | DEBUG    | resource_pack_manager.py:258 | get_texture_path() | [TEXTURE FOUND - PRIMARY] ns=minecraft, rel=block/water, abs=/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png
2025-09-01 19:11:37.262 | ERROR    | resource_pack_manager.py:303 | _get_model() | Failed to load block model {'model': 'minecraft:block/water'}
'/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
Call stack:
  File "/usr/lib/python3.12/threading.py", line 1012, in run
    self._target(*self._args, **self._kwargs)
  File "/app/lib/python3.12/site-packages/amulet_map_editor/programs/edit/api/chunk_generator.py", line 32, in _generate_chunks
    self.thread_action()
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/thread_generator.py", line 48, in thread_action
    self._objects[self._obj_index].thread_action()
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/mesh/level/level.py", line 168, in thread_action
    chunk.create_geometry()
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/mesh/level/chunk/chunk.py", line 185, in create_geometry
    chunk_verts, chunk_verts_translucent = self._create_lod0_multi(
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/mesh/level/chunk/chunk_builder.py", line 73, in _create_lod0_multi
    return create_lod0_chunk(
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/resource_pack/resource_pack.py", line 203, in get_block_model
    self._block_models[universal_block] = self._resource_pack.get_block_model(version_block)
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/base/resource_pack_manager.py", line 74, in get_block_model
    + tuple(self._get_model(block_) for block_ in block.extra_blocks)
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/base/resource_pack_manager.py", line 74, in <genexpr>
    + tuple(self._get_model(block_) for block_ in block.extra_blocks)
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 303, in _get_model
    log.error(f"Failed to load block model {model}\n{e}\nCall stack:\n" + "".join(traceback.format_stack(limit=10)))

The files are all there. I can run a shell prompt inside my flatpak, and list the files right where it says they’re missing. All these .png and .json files, and all the subfolders they reside in under the folder java_vanilla_fix are ALL bundled with the “minecraft_resource_pack” package and they’re all present in the source wheel used in the flatpak construction. The DEBUG output proves this:

2025-09-01 19:11:33.385 | DEBUG    | resource_pack_manager.py:235 | _load_iter() | [SANITY:PRIMARY] {('minecraft', 'block/water_still'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water_still.png', True), ('minecraft', 'block/lava_flow'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava_flow.png', True), ('minecraft', 'block/lava_still'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava_still.png', True), ('minecraft', 'block/water_flow'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water_flow.png', True), ('minecraft', 'block/water_overlay'): ('/home/seann/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/water_overlay.png', True), ('minecraft', 'block/lava'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png', True), ('minecraft', 'block/water'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png', True)}
2025-09-01 19:11:33.385 | DEBUG    | resource_pack_manager.py:236 | _load_iter() | [SANITY:BACKUP ] {('minecraft', 'block/water_still'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water_still.png', True), ('minecraft', 'block/lava_flow'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava_flow.png', True), ('minecraft', 'block/lava_still'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava_still.png', True), ('minecraft', 'block/water_flow'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water_flow.png', True), ('minecraft', 'block/water_overlay'): ('/home/seann/.var/app/io.github.evilsupahfly.amulet_flatpak/cache/AmuletMapEditor/resource_packs/java/vanilla/assets/minecraft/textures/block/water_overlay.png', True), ('minecraft', 'block/lava'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png', True), ('minecraft', 'block/water'): ('/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png', True)}

Also, Amulet is able to download the minecraft version-secific textures from the Minecraft launcher website after loading a Minecraft save from the user’s $HOME/.minecraft/saves folder, and save them to the XDG-defined cache, but it fails to read the files bundled with its own component, minecraft_model_reader.

To get around this, I figured I would simply have the bundled texture folder copied to cache, and use them from that location instead, so I modified the minecraft_model_reader module to do just this, and it still failed. Inside Amulet, the paths are defined as follows:

data_dir = platformdirs.user_data_dir("AmuletMapEditor", "AmuletTeam")
os.environ.setdefault("DATA_DIR", data_dir)
config_dir = platformdirs.user_config_dir("AmuletMapEditor", "AmuletTeam")
if config_dir == data_dir:
    config_dir = os.path.join(data_dir, "Config")
os.environ.setdefault("CONFIG_DIR", config_dir)
os.environ.setdefault("CACHE_DIR", platformdirs.user_cache_dir("AmuletMapEditor", "AmuletTeam"))
os.environ.setdefault("LOG_DIR", platformdirs.user_log_dir("AmuletMapEditor", "AmuletTeam"))

So… Can somebody please explain to me why this works fine when I install it into a VENV with PIP but fails when the exact same code is built into a flatpak?

The java_vanilla_fix folder bundled with minecraft_model_reader contains about 400 files, while the primary cache contains about 9,900 - am I up against a ulimit cap or limit, and if so, can I extend that ceiling within the flatpak or am I bound by the ulimit defined by the host system? If it’s not ulimit, what other reason is there for the app to successfully locate the files, then suddenly say it can’t find them?

The Python code itself is sound, because there are no issues at all when installed inside a VENV. And while I suppose everybody could just do that, I figured making it into a flatpak would be easier for novice users who might not understand the complexities of creating and maintaining a Python virtual environment.

If you need anything clarified or want to see anything, the entire flatpak project is located in my GIT repo. The sum total of this project is all there: all the YAML/JSON manifest files, all the packages I modified for debug logging, even the shell scripts I run locally to automate everything so I don’t have to keep entering commands each step of the way. Literally EVERYTHING.

Amulet is a fantastic tool, but it’s not very effective with missing textures so I would love to get to the bottom of this!

So, about this:

  - --filesystem=host
  - --filesystem=host-os
  - --filesystem=home
  - --filesystem=/tmp
  - --filesystem=xdg-config/AmuletMapEditor:create
  - --filesystem=xdg-cache/AmuletMapEditor:create
  - --filesystem=xdg-run/gvfs
  - --filesystem=xdg-run/gvfsd

You really, really don’t need this and shouldn’t do this. Why not a simple --filesystem=~/.minecraft, if you need the .minecraft folder?

As for your cache directory:
Flatpak uses a custom location for data, cache and config folders. In your case, you would find them under ~/.var/app/io.github.evilsupahfly.amulet_flatpak. It could just be that you have a mismatch here when writing and reading, so the file lands in a place where it isn’t expected.

Well, initially I just had

- --filesystem=home

which would allow access to ~/.minecraft by default, as well as non-standard locations, accounting for third party launchers, modded installations, etc. The problem is that the missing textures have been a problem since day 1 and all those extras got added during troubleshooting.

The app-specific locations for cache, config, and logging all work fine inside the flatpak sandbox, both before and after the addition of these extra lines but the problem files aren’t in the cache - they’re bundled with one of the installed packages. The failures come from trying to read the files in /app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix. As I explained above, the log shows that Python acknowledges the files are where they’re supposed to be but something still causes Amulet to trip up:

2025-09-01 19:11:37.261 | DEBUG    | resource_pack_manager.py:247 | get_texture_path() | [PROBE:TEXTURE] Called with ns=minecraft, rel=block/water
2025-09-01 19:11:37.261 | DEBUG    | resource_pack_manager.py:258 | get_texture_path() | [TEXTURE FOUND - PRIMARY] ns=minecraft, rel=block/water, abs=/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png
2025-09-01 19:11:37.262 | ERROR    | resource_pack_manager.py:303 | _get_model() | Failed to load block model {'model': 'minecraft:block/water'}
'/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png'
Call stack:
  File "/usr/lib/python3.12/threading.py", line 1012, in run
    self._target(*self._args, **self._kwargs)
  File "/app/lib/python3.12/site-packages/amulet_map_editor/programs/edit/api/chunk_generator.py", line 32, in _generate_chunks
    self.thread_action()
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/thread_generator.py", line 48, in thread_action
    self._objects[self._obj_index].thread_action()
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/mesh/level/level.py", line 168, in thread_action
    chunk.create_geometry()
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/mesh/level/chunk/chunk.py", line 185, in create_geometry
    chunk_verts, chunk_verts_translucent = self._create_lod0_multi(
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/mesh/level/chunk/chunk_builder.py", line 73, in _create_lod0_multi
    return create_lod0_chunk(
  File "/app/lib/python3.12/site-packages/amulet_map_editor/api/opengl/resource_pack/resource_pack.py", line 203, in get_block_model
    self._block_models[universal_block] = self._resource_pack.get_block_model(version_block)
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/base/resource_pack_manager.py", line 74, in get_block_model
    + tuple(self._get_model(block_) for block_ in block.extra_blocks)
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/base/resource_pack_manager.py", line 74, in <genexpr>
    + tuple(self._get_model(block_) for block_ in block.extra_blocks)
  File "/app/lib/python3.12/site-packages/minecraft_model_reader/api/resource_pack/java/resource_pack_manager.py", line 303, in _get_model
    log.error(f"Failed to load block model {model}\n{e}\nCall stack:\n" + "".join(traceback.format_stack(limit=10)))

The Python 3.12 interpreter running in the flatpak sandbox confirms that the “missing” files do in fact exist, and they are located exactly where they should be. However, some fundamental difference between the flatpak sandbox and a Python 3.12 VENV running the same packages from the same local install causes these files to fail after being located by Python and before being loaded into Pillow.

The textures downloaded to the cache from the Minecraft site all work just fine, although strangely enough, copying the files from the bundled location to the cache also failed to resolve the issue. The problem is that this only happens in the flatpak build. I can run this same build in a VENV with all the same packages and it runs just fine. Logging hasn’t offered any new insights because Python itself tells me the files are there, then promptly fails to load them without telling me why.