jely2002/youtube-dl-gui · error · Error
Orphaned media item found.
Error message
Orphaned media item found.
What it means
processMediaAddPayload attaches a newly added media item to its group. Before mutating group.items it verifies the group exists; if findGroupById returns undefined it throws 'Orphaned media item found.' The store requires every media item to belong to a live group.
Solutions
- Verify the group is created (and present in groupOrder) before any media add payload for it can be processed.
- Guard the caller: skip the payload if groupStore.findGroupById(groupId) is undefined.
- Make group removal cancel/flush pending add events for that group first.
- Add a try/catch around processMediaAddPayload to log and drop orphaned payloads instead of propagating.
Example fix
// before
function handleMediaAdd(payload: MediaAddPayload) {
processMediaAddPayload(payload);
}
// after
function handleMediaAdd(payload: MediaAddPayload) {
if (!groupStore.findGroupById(payload.groupId)) return; // stale add payload
processMediaAddPayload(payload);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!groupStore.findGroupById(payload.groupId)) return; // drop orphaned add payload
Type guard
const hasGroup = (groupId: string): boolean => groupStore.findGroupById(groupId) !== undefined;
Try / catch
try {
processMediaAddPayload(payload);
} catch (e) {
if (e instanceof Error && e.message.includes('Orphaned media item')) {
console.warn('Dropped add event for missing group', payload.groupId);
return;
}
throw e;
} Prevention
- Create the group before enqueueing any media add payloads for it.
- Cancel pending events for a group before removing it.
- Log-and-drop stale events in a single wrapper around event dispatch.
When it happens
Trigger: A MediaAddPayload event with a groupId that has no matching group — the group was deleted before the add payload arrived, the add event is replayed after the group list was cleared, or the backend and frontend group registries are out of sync.
Common situations: Rapid cancel/remove of a group during download start; stale WebSocket/Tauri events delivered after state reset; races between group teardown and queued add payloads.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Orphaned media item found during error handling.
- Playlist group is missing entry metadata.
- No options found for group
AI-assisted analysis of jely2002/youtube-dl-gui@c402ee39c0 (2026-09-12).
Data as JSON: /api/errors/9c6636e4c7aa85c4.
Report an issue: GitHub.
Appendix: source
Thrown at src/stores/media/media.ts:89
return;
}
for (const newGroup of newGroups) {
stateStore.setGroupState(newGroup.id, MediaState.configure);
}
} else {
groupStore.consolidateGroup(group);
void notifyGroup(NotificationKind.PlaylistReady, group, {}, group.entries?.length ?? 1);
stateStore.setGroupState(group.id, MediaState.configure);
resolvePendingReadyGroup(group.id, [group.id]);
}
}
function processMediaAddPayload(payload: MediaAddPayload) {
const { item, groupId, total } = payload;
item.groupId = groupId;
const group = groupStore.findGroupById(groupId);
if (!group) throw new Error('Orphaned media item found.');
if (item.entries) {
const existingId = Object.keys(group.items)[0];
if (existingId && existingId !== item.id) {
delete group.items[existingId];
}
item.isLeader = true;
group.items[item.id] = item;
const { id, groupId: gid, isLeader, ...meta } = item;
void id;
void gid;
void isLeader;
Object.assign(group, meta);
group.total = total;
group.processed = 0;
if (group.skipPlaylistSelection) {
void expandPlaylistGroup(groupId, { rows: [] }).catch((error) => {View on GitHub (pinned to c402ee39c0)