odysseus-dev/odysseus · warning · Error

HTTP ${res.status}

Error message

HTTP ${res.status}

What it means

Fallback error thrown by _doClearTaskCache when POST /api/tasks/{id}/clear-cache fails. The code prefers data.detail, then data.error, and only falls back to `HTTP {status}` when the body is neither ok nor carries either field. The catch wrapper prefixes it as 'Clear cache failed: ...' in a toast.

Source

Thrown at static/js/tasks.js:1932

    if (!res.ok) throw new Error('Failed to revert task');
    if (uiModule) uiModule.showToast('Reverted to default');
    await _fetchTasks();
    _renderMainView();
  } catch (e) { if (uiModule) uiModule.showError(e.message); }
}

async function _doClearTaskCache(id, label = 'cache') {
  const ok = uiModule?.styledConfirm
    ? await uiModule.styledConfirm(`Clear cached ${label} for this task?`, { confirmText: 'Clear' })
    : confirm(`Clear cached ${label} for this task?`);
  if (!ok) return;
  try {
    const res = await fetch(`${API_BASE}/api/tasks/${encodeURIComponent(id)}/clear-cache`, {
      method: 'POST',
      credentials: 'same-origin',
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok || !data.ok) throw new Error(data.detail || data.error || `HTTP ${res.status}`);
    const n = Object.values(data.cleared || {}).reduce((a, b) => a + Number(b || 0), 0) + Number(data.files || 0);
    if (uiModule) uiModule.showToast(`Cleared ${label}${n ? ` (${n})` : ''}`);
  } catch (e) {
    if (uiModule) uiModule.showError(`Clear cache failed: ${e.message || e}`);
  }
}

async function _doToggleAll() {
  // If any task is active → pause all. Else resume all paused tasks.
  const hasActive = _tasks.some(t => t.status === 'active');
  const targets = _tasks.filter(t => t.status === (hasActive ? 'active' : 'paused'));
  if (targets.length === 0) {
    if (uiModule) uiModule.showToast('No tasks to ' + (hasActive ? 'pause' : 'resume'));
    return;
  }
  const verb = hasActive ? 'Pause' : 'Resume';
  let confirmed = true;
  if (uiModule?.styledConfirm) {

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Check the status code shown in the toast: 404 = task missing, 401/403 = re-login, 500 = server-side cache clear failure (check logs)
  2. Refresh the task list before clearing cache if the task may have been removed
  3. If a proxy sits in front, make sure it preserves JSON error responses for /api/tasks/*
Defensive patterns

Strategy: try-catch

Validate before calling

if (!_tasks.some(t => t.id === id)) { showToast('Task not found — refresh list'); return; }

Try / catch

try { await _doClearTaskCache(id, label); } catch (e) { /* toast already shown by _doClearTaskCache */ }

Prevention

When it happens

Trigger: Clearing a task's cache for a task id that doesn't exist (404), when the server returns 200 but data.ok is falsy without detail/error fields, when auth fails (401/403), or when the response is non-JSON (the .catch(() => ({})) yields an empty object).

Common situations: Task list is stale and the task was deleted server-side; proxy or gateway returns an HTML error page; session expired.

Related errors


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