The image cache directory is never created, so the dashboard reports its space as unknown #179

Closed
opened 2026-08-22 17:01:27 +02:00 by Claude · 1 comment
Collaborator

Found on the dashboard of the throwaway instance in TESTCONTAINER/.

What it looks like

The dashboard's Paths panel draws every folder with the space on its
filesystem — On filesystem: /config · 1.1 TiB / 1.8 TiB — except one:

Image Cache
/cache/images
On filesystem: ?                                    ? / ?

What answers

GET /System/Info/Storage:

"ImageCacheFolder": { "Path": "/cache/images", "FreeSpace": -1, "UsedSpace": -1 },
"CacheFolder":      { "Path": "/cache", "DeviceId": "/cache",
                      "StorageType": "Fixed",
                      "FreeSpace": 755006566400, "UsedSpace": 1240977825792 }

ImageCacheFolder is the only entry with no DeviceId and no StorageType.
The reason is on disk: <cache>/ holds transcodes/ and nothing else. The
image cache directory is never created, so there is nothing to statfs.

Where to start

Whatever creates <cache>/transcodes at startup should create the image cache
directory beside it. Upstream creates its application paths up front, which is
why the same panel is never short a row there.

How to know it is done

A first start against an empty program-data directory leaves the image cache
directory on disk, and /System/Info/Storage reports it with the same
DeviceId, StorageType, FreeSpace and UsedSpace shape as every other
folder.

House rules

Tests run under cargo nextest; upstream's source is the checkout in
upstream/ at the pin. Generated artifacts are regenerated, never edited.

Found on the dashboard of the throwaway instance in `TESTCONTAINER/`. ## What it looks like The dashboard's **Paths** panel draws every folder with the space on its filesystem — `On filesystem: /config · 1.1 TiB / 1.8 TiB` — except one: ``` Image Cache /cache/images On filesystem: ? ? / ? ``` ## What answers `GET /System/Info/Storage`: ```json "ImageCacheFolder": { "Path": "/cache/images", "FreeSpace": -1, "UsedSpace": -1 }, "CacheFolder": { "Path": "/cache", "DeviceId": "/cache", "StorageType": "Fixed", "FreeSpace": 755006566400, "UsedSpace": 1240977825792 } ``` `ImageCacheFolder` is the only entry with no `DeviceId` and no `StorageType`. The reason is on disk: `<cache>/` holds `transcodes/` and nothing else. The image cache directory is never created, so there is nothing to `statfs`. ## Where to start Whatever creates `<cache>/transcodes` at startup should create the image cache directory beside it. Upstream creates its application paths up front, which is why the same panel is never short a row there. ## How to know it is done A first start against an empty program-data directory leaves the image cache directory on disk, and `/System/Info/Storage` reports it with the same `DeviceId`, `StorageType`, `FreeSpace` and `UsedSpace` shape as every other folder. ### House rules Tests run under `cargo nextest`; upstream's source is the checkout in `upstream/` **at the pin**. Generated artifacts are regenerated, never edited.
Claude 2026-08-22 17:01:51 +02:00
  • closed this issue
  • added the
    p3
    label
Author
Collaborator

Not a deviation — measured against the reference instance at the pin, which
answers exactly what we answer.

GET /System/Info/Storage   (upstream v12.0-rc5, 6d501ba4)
"ImageCacheFolder": { "Path": "/cache/images",     "FreeSpace": -1, "UsedSpace": -1 }
"WebFolder":        { "Path": "/app/jellyfin-web", "FreeSpace": -1, "UsedSpace": -1 }

Both are directories that are not there — reference/var/cache/ holds
transcodes and CACHEDIR.TAG and no images, and the image is built
--nowebclient. Upstream's StorageHelper.ResolvePath calls
DirectoryInfo.ResolveLinkTarget, which throws rather than answering for a path
that is not there, and GetFreeSpaceOf catches that into -1. Nothing creates
the image cache at startup on either server: upstream writes it lazily under
ImageProcessor.ResizedImageCachePath when it caches a resized picture, and
this server caches none.

So the dashboard reads ? / ? against upstream too, and canonicalize refusing
a path that is not there is the answer rather than the bug. The fix written for
this is reverted in 49540ea.

Two things a review turned up while measuring, both pre-existing and neither
measured against a live upstream, so they are noted rather than filed: under()
matches whole segments where upstream's drive match is a raw StartsWith, and
canonicalize normalises .. where upstream keeps it literal. Each needs a
mount arrangement to show, and neither is reachable through a path this server
reports.

Not a deviation — measured against the reference instance at the pin, which answers exactly what we answer. ``` GET /System/Info/Storage (upstream v12.0-rc5, 6d501ba4) "ImageCacheFolder": { "Path": "/cache/images", "FreeSpace": -1, "UsedSpace": -1 } "WebFolder": { "Path": "/app/jellyfin-web", "FreeSpace": -1, "UsedSpace": -1 } ``` Both are directories that are not there — `reference/var/cache/` holds `transcodes` and `CACHEDIR.TAG` and no `images`, and the image is built `--nowebclient`. Upstream's `StorageHelper.ResolvePath` calls `DirectoryInfo.ResolveLinkTarget`, which throws rather than answering for a path that is not there, and `GetFreeSpaceOf` catches that into `-1`. Nothing creates the image cache at startup on either server: upstream writes it lazily under `ImageProcessor.ResizedImageCachePath` when it caches a resized picture, and this server caches none. So the dashboard reads `? / ?` against upstream too, and `canonicalize` refusing a path that is not there is the answer rather than the bug. The fix written for this is reverted in `49540ea`. Two things a review turned up while measuring, both pre-existing and neither measured against a live upstream, so they are noted rather than filed: `under()` matches whole segments where upstream's drive match is a raw `StartsWith`, and `canonicalize` normalises `..` where upstream keeps it literal. Each needs a mount arrangement to show, and neither is reachable through a path this server reports.
Sign in to join this conversation.
No description provided.