Before reporting
What happened?
After separating a track, the studio player shows most stem lanes greyed out and I can't play anything — even though all 6 stems were separated successfully and exist on disk.
The player only loads original + vocals ([player] canplay — 2 stems) and greys out drums, bass, guitar, piano, other. The library lists the track as "· 1 stem". But:
- On disk, all stems are present and valid (79 MB each, correct 7:49 duration):
jobs/ed6d76809143/stems/
bass.wav drums.wav guitar.wav original.wav other.wav piano.wav vocals.wav
GET /api/jobs/ed6d76809143 reports all of them:
{ "status": "done",
"stems": ["original","vocals","drums","bass","guitar","piano","other"] }
- But the player only requests 2 of them over the network:
GET /api/jobs/ed6d76809143/stems/original.wav → 206
GET /api/jobs/ed6d76809143/stems/vocals.wav → 206
(no request for drums/bass/guitar/piano/other)
So the separation is fine; the player just doesn't load the stems that are actually there, which leaves the deck unusable.
Likely root cause (code trace)
The player wires audio from the persisted job state's stem list, not from what's present on disk / returned by the job-detail endpoint:
catalog.js:656 → wireUpAudio(trackId, track.audioStems, ...)
track.audioStems comes from catalog.js:367 → audioStems: state.stems || fallbackTrack.audioStems || []
- For this track that persisted
state.stems only contains [original, vocals] (hence "1 stem" = stemCount excluding original), so wireUpAudio (player.js:960) only wires 2 lanes and greys the rest.
In other words: when the recorded/selected stem set is narrower than what's on disk, the player trusts the recorded set and ignores stems that exist. Reconciling wireUpAudio's stem list against the job-detail stems (or the on-disk stems/ dir) would fix it.
I believe the narrower recorded set came from a vocals-only / vocal-split separation — htdemucs_6s still wrote all 6 stems to disk, but the job state recorded only the selected one.
Steps to reproduce
- Import a track (YouTube URL) and separate it with only Vocals selected (or via the vocal-split path).
- Open the finished track from the library.
- Observe: the deck loads only
original + vocals; the other 5 lanes are greyed and the transport is unusable — despite all 6 *.wav files existing under jobs/<id>/stems/.
Expected: the player loads/plays every stem that exists on disk for the job (or at least the full set the job produced), not only the recorded subset.
Operating system
macOS 26.6.1 (arm64, Apple Silicon)
StemDeck version
0.15.3.dev5+gab95be7ad (source, commit ab95be7)
How did you install it?
From source on macOS: git clone + ./run.sh setup && ./run.sh start (localhost:8000). Compute device: MPS.
Logs
[player] canplay — 2 stems, ctx=running, audios: [original, vocals, drums, bass, guitar, piano, other, undefined:R]
Server also logged repeated WARNING: [youtube] No supported JavaScript runtime could be found during import (separate/minor — bundled yt-dlp runs without a JS runtime), but the separation completed and stems were written regardless.
Before reporting
main, commitab95be7) and the issue still happens.What happened?
After separating a track, the studio player shows most stem lanes greyed out and I can't play anything — even though all 6 stems were separated successfully and exist on disk.
The player only loads
original+vocals([player] canplay — 2 stems) and greys outdrums,bass,guitar,piano,other. The library lists the track as "· 1 stem". But:GET /api/jobs/ed6d76809143reports all of them:{ "status": "done", "stems": ["original","vocals","drums","bass","guitar","piano","other"] }So the separation is fine; the player just doesn't load the stems that are actually there, which leaves the deck unusable.
Likely root cause (code trace)
The player wires audio from the persisted job state's stem list, not from what's present on disk / returned by the job-detail endpoint:
catalog.js:656→wireUpAudio(trackId, track.audioStems, ...)track.audioStemscomes fromcatalog.js:367→audioStems: state.stems || fallbackTrack.audioStems || []state.stemsonly contains[original, vocals](hence "1 stem" =stemCountexcludingoriginal), sowireUpAudio(player.js:960) only wires 2 lanes and greys the rest.In other words: when the recorded/selected stem set is narrower than what's on disk, the player trusts the recorded set and ignores stems that exist. Reconciling
wireUpAudio's stem list against the job-detail stems (or the on-diskstems/dir) would fix it.I believe the narrower recorded set came from a vocals-only / vocal-split separation —
htdemucs_6sstill wrote all 6 stems to disk, but the job state recorded only the selected one.Steps to reproduce
original+vocals; the other 5 lanes are greyed and the transport is unusable — despite all 6*.wavfiles existing underjobs/<id>/stems/.Expected: the player loads/plays every stem that exists on disk for the job (or at least the full set the job produced), not only the recorded subset.
Operating system
macOS 26.6.1 (arm64, Apple Silicon)
StemDeck version
0.15.3.dev5+gab95be7ad(source, commitab95be7)How did you install it?
From source on macOS:
git clone+./run.sh setup && ./run.sh start(localhost:8000). Compute device: MPS.Logs
Server also logged repeated
WARNING: [youtube] No supported JavaScript runtime could be foundduring import (separate/minor — bundled yt-dlp runs without a JS runtime), but the separation completed and stems were written regardless.