Sessions
Fadenza saves your playlists and what you think of the music in them. There is no library database and no cache that matters, beyond the two files below.
What comes back
Quit and reopen, and you get:
- Every playlist, in order, with its own tracks
- Which playlist you were viewing, and which one was playing
- The current track and whatever you had selected — kept per playlist, as are repeat mode, shuffle and each list’s own sort and grouping
- The playback position, to the second
- Repeat mode
- Shuffle: whether it is on, and the exact order it generated
- Each playlist’s own sort column and grouping
- Volume, and mute as its own state
- Your output device preference
- Watched folders, including the tracks you dismissed from them
Playback resumes paused. Fadenza never starts making noise because you opened it. The position is set, the track is loaded, and it waits.
The shuffle order is saved rather than regenerated, which is why a restored session continues the same sequence instead of reshuffling. It is also what makes the behaviour testable, which is the reason it works.
Two files, not one
Your playlists live in session.json. Your ratings and play counts live beside it in
user-state.json, and the split is deliberate: the first describes what you were doing, the
second describes what you think of your music.
They are treated differently on purpose. A session can be rebuilt by re-adding files; a rating
cannot be recovered from anything. So user-state.json is never evicted, never discarded when its
format changes — it is migrated instead — and it is written out when you quit rather than only on
a timer.
Where it lives
~/Library/Containers/com.ray.Fadenza/Data/Library/Application Support/com.ray.Fadenza/session.json
That container path is where the App Sandbox actually puts it — attach the file from there, not
from an unsandboxed ~/Library/Application Support/, if you’re pulling it for a bug report.
It is written about a second after you stop changing things — a drag that fires twenty events produces one write — and flushed immediately when you quit. Writes are atomic, so a crash halfway through cannot leave you with half a session.
What is not saved
- Anything transient: buffering state, error banners, in-flight work.
- Decoded artwork, which is cached in memory and rebuilt on demand.
- The remote API token. That lives in the Keychain and appears in neither the session file nor the logs.
File access after a restart
macOS sandboxing means an app cannot simply reopen a file by path after a restart; it has to save a token for each file or folder you granted it. Fadenza saves those tokens alongside your playlists and resolves them on launch.
If one no longer resolves — you moved the file, or the permission went stale — the track is marked missing and kept in the list, with an offer to reopen the file panel so you can grant access again. It is not removed, and you are not left guessing which track disappeared.
If the file breaks
A session file that cannot be read is moved aside, never deleted:
session-corrupt-1.json
Up to three are kept. Fadenza then launches with just the Queue, empty, and a banner telling you what happened and where the file went.
Keeping it matters twice over: your playlists may be recoverable by hand, and a bug report with the file attached is worth far more than one without it.
The same refusal applies to a session file written by a newer version of Fadenza than the one reading it: rather than guess at fields it does not recognise, Fadenza takes the same move-aside path and preserves the file untouched, instead of best-effort decoding it and risking a write that overwrites what it could not fully read.
Upgrades
The session file carries a version. Every version bump ships with a migration from the previous one and a test that runs it against a real file from that version — including versions older than the last. A migration that quietly dropped a field would turn into a playlist that quietly loses tracks, which is the one thing this app is built not to do.