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

  1. Verify the group is created (and present in groupOrder) before any media add payload for it can be processed.
  2. Guard the caller: skip the payload if groupStore.findGroupById(groupId) is undefined.
  3. Make group removal cancel/flush pending add events for that group first.
  4. 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

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


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)