odysseus-dev/odysseus · error · Error

Failed to pause task

Error message

Failed to pause task

What it means

Thrown by _pauseTask (static/js/tasks.js:139) when POST /api/tasks/{id}/pause returns non-2xx; generic 'Failed to pause task' hides the status. Pause is a state transition on a live task, so failures cluster around the task's current lifecycle state rather than validation.

Source

Thrown at static/js/tasks.js:139

    const existing = card.querySelector('.task-card-delete-busy');
    if (!active) {
      existing?.remove();
      continue;
    }
    if (!existing) {
      const badge = document.createElement('span');
      badge.className = 'task-card-delete-busy';
      badge.innerHTML = '<span class="task-card-delete-busy-label">Deleting</span><span class="task-card-delete-busy-spin" aria-hidden="true"></span>';
      card.appendChild(badge);
    }
  }
}

async function _pauseTask(id) {
  const res = await fetch(`${API_BASE}/api/tasks/${id}/pause`, {
    method: 'POST', credentials: 'same-origin',
  });
  if (!res.ok) throw new Error('Failed to pause task');
}

async function _resumeTask(id) {
  const res = await fetch(`${API_BASE}/api/tasks/${id}/resume`, {
    method: 'POST', credentials: 'same-origin',
  });
  if (!res.ok) throw new Error('Failed to resume task');
}

async function _runNow(id, force = false) {
  const res = await fetch(`${API_BASE}/api/tasks/${id}/run${force ? '?force=true' : ''}`, {
    method: 'POST', credentials: 'same-origin',
  });
  if (!res.ok) {
    // Surface the backend's actual reason — 409 means "already running",
    // 404 task missing, etc. Previously every error rendered as the same
    // generic "Failed to trigger task", which hid the cause.
    let msg = `Failed to trigger task (${res.status})`;

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. On failure, re-fetch the task list and re-render — the card's state label will show the true current state (paused/running) and usually explains the rejection.
  2. Treat 'already paused' outcomes as success and sync UI state.
  3. Add the status to the error message: `\`Failed to pause task (HTTP ${res.status})\``.
  4. Re-login on 401; on 403 verify you own the task.

Example fix

// before
if (!res.ok) throw new Error('Failed to pause task');
// after
if (!res.ok) throw new Error(`Failed to pause task (HTTP ${res.status})`);
Defensive patterns

Strategy: try-catch

Try / catch

try { await _pauseTask(id); } catch (err) { await refreshTasks(); // re-sync true state — most failures are state races showError(err.message); }

Prevention

When it happens

Trigger: Clicking pause on a running task: POST /api/tasks/{id}/pause. 404 task deleted; 409 when the task is not in a pausable state (already paused, mid-run lock); 403 non-owner; 401 expired session; 500 scheduler error.

Common situations: Pause clicked while the task is between runs or already paused from another tab; task deleted since the list rendered; ownership mismatch.

Related errors


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