odysseus-dev/odysseus · warning · Error

data.error

Error message

data.error

What it means

Application-level error after a successful HTTP 200 from GET /api/model/cached: the JSON body contains a truthy error field, meaning the backend completed the request but the cache scan itself failed (e.g. directory unreadable, remote probe error). The raw data.error string becomes the message and the UI shows the failure panel with Retry.

Source

Thrown at static/js/cookbookServe.js:4216

      const tagContainer = document.getElementById('serve-tags');
      if (tagContainer) tagContainer.innerHTML = '';
      return;
    }
    const res = await fetch(`/api/model/cached${params}`);
    if (!res.ok) {
      const body = await res.text().catch(() => '');
      let msg = '';
      try {
        const payload = JSON.parse(body);
        msg = payload && (payload.detail || payload.error || payload.message);
      } catch {
        msg = body;
      }
      msg = typeof msg === 'string' ? msg.trim() : '';
      throw new Error(`HTTP ${res.status} ${res.statusText}${msg ? `: ${msg}` : ''}`);
    }
    const data = await res.json();
    if (data && data.error) throw new Error(data.error);
    _writeCachedModelScan(scanSig, data);
    _dlWp.destroy();
    _renderCachedModelsData(list, data, host);
  } catch (e) {
    _dlWp.destroy();
    list.innerHTML = `<div class="hwfit-loading" style="flex-direction:column;gap:8px;text-align:center;"><div style="color:var(--red);font-weight:600;">Cached model scan failed</div><div style="font-size:11px;opacity:0.65;max-width:420px;line-height:1.4;">${esc(e.message)}</div><button type="button" class="hwfit-gpu-btn serve-empty-scan-btn" style="height:26px;padding:3px 10px;">Retry</button></div>`;
    list.querySelector('.serve-empty-scan-btn')?.addEventListener('click', () => {
      _fetchCachedModels(true);
    });
  }
}

/** Filter presets matching a model repo */
function _presetsForModel(presets, repo) {
  const short = repo.split('/').pop();
  return presets.filter(p => {
    const pm = p.model || ''; const pn = p.name || '';
    return pm === repo || pn === repo || pm.split('/').pop() === short || pn === short;

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Read data.error — it names the exact backend failure; fix path/permissions accordingly
  2. Confirm the models cache path configured on the backend exists and is listable by the server user
  3. If remote, verify SSH access and the remote path
  4. Retry the scan after the fix (Retry button)
Defensive patterns

Strategy: type-guard

Type guard

function isCachedModelScan(d) {
  return !!d && typeof d === 'object' && !d.error && Array.isArray(d.models || d.items || d.cached);
}

Try / catch

const data = await res.json();
if (data && data.error) {
  renderScanFailureWithRetry(list, data.error, () => _fetchCachedModels(true));
  return; // application-level failure: don't throw into the transport catch
}
_writeCachedModelScan(scanSig, data);

Prevention

When it happens

Trigger: 200 response shaped {error:'...'} — models directory missing or unreadable, remote host probe returned an error string, cache path misconfigured in backend settings.

Common situations: Cache directory moved or deleted; running in a container without the models volume mounted; remote cache host reachable but the path in config is wrong; partial JSON from a truncated upstream scan.

Related errors


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