odysseus-dev/odysseus · error · Error

Failed to delete session

Error message

Failed to delete session

What it means

Generic user-facing toast shown when deleting a chat session fails. The try block covers three distinct failure points: dynamic import of presets.js (silently swallowed), the DELETE /api/session/{sid} call (any non-2xx throws 'Failed'), and loadSessions(). The catch conflates them into one message.

Source

Thrown at static/js/sessions.js:2445

    uiModule.showToast('Unfavorite before deleting');
    return false;
  }
  if (!await uiModule.styledConfirm('Delete this session?', { confirmText: 'Delete', danger: true })) {
    return false;
  }
  if (window.chatModule && window.chatModule.abortCurrentRequest) {
    window.chatModule.abortCurrentRequest();
  }
  _deselectCurrentSession(sid);
  _removeSessionFromLocalState(sid);
  _skipAutoSelect = true;
  try {
    const pm = await import('./presets.js');
    if (pm.removePersistentChat) pm.removePersistentChat(sid);
  } catch (e) {}
  try {
    const res = await fetch(`${API_BASE}/api/session/${sid}`, { method: 'DELETE' });
    if (!res.ok) throw new Error('Failed');
    uiModule.showToast('Session deleted');
  } catch (e) {
    uiModule.showError('Failed to delete session');
  }
  await loadSessions();
  return true;
}

// Session list keyboard navigation: arrows to move, Delete to delete
async function _onSessionListKeydown(e) {
  const item = e.target.closest('.list-item[data-session-id]');
  if (!item) return;

  if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
    e.preventDefault();
    // Get all visible session items across all containers
    const allItems = Array.from(document.querySelectorAll('#session-list .list-item[data-session-id]'));
    const idx = allItems.indexOf(item);

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Check server logs / network tab for the DELETE status code to identify which failure fired
  2. Retry after reloading sessions (loadSessions()) to refresh stale IDs
  3. Ensure auth credentials are valid and API_BASE points at the running backend
  4. Improve the catch to distinguish network vs HTTP errors (log e, include res.status in the message)

Example fix

// before
  } catch (e) {
    uiModule.showError('Failed to delete session');
  }
  await loadSessions();

// after
  } catch (e) {
    console.error('delete session failed:', e);
    uiModule.showError('Failed to delete session');
  }
  try { await loadSessions(); } catch (e) { console.error('reload failed:', e); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!sid) return false;
if (!navigator.onLine) { uiModule.showError('Offline — cannot delete session'); return false; }

Try / catch

try { /* fetch + delete */ } catch (e) { console.error('delete session', sid, e); uiModule.showError(e?.message?.startsWith('HTTP') ? `Delete failed (${e.message})` : 'Failed to delete session'); }

Prevention

When it happens

Trigger: DELETE /api/session/{sid} returns 4xx/5xx (session already deleted on server, auth cookie expired, server restarted and lost in-memory store), the server is unreachable (network offline), or the trailing await loadSessions() rejects.

Common situations: Stale session list after another tab/device deleted the session; app reload mid-delete; dev server restart wiping sessions; expired auth credentials.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/582986d6beceefe9. Report an issue: GitHub.