odysseus-dev/odysseus · warning · Error
data.error || 'scan failed'
Error message
data.error || 'scan failed'
What it means
Application-level error from the GGUF picker scan: GET /api/cookbook/hf-gguf-files answered HTTP 200 but the JSON body has ok falsy (or data.error set), meaning the backend itself failed to list GGUF files for the repo. The message is data.error or the generic 'scan failed'.
Source
Thrown at static/js/cookbook.js:2406
if (!dlGgufRow || !dlGgufQuant || !dlGgufNote) return false;
const rawRepo = _stripHfUrl(rawValue || '');
const ollamaName = _ollamaName(rawRepo);
const fileSplit = !ollamaName ? _splitRepoFile(rawRepo) : null;
const split = ollamaName ? { repo: ollamaName, include: null } : (fileSplit || _splitRepoTag(rawRepo));
const repo = split.repo || '';
if (ollamaName || split.include || !/^[^\s/]+\/[^\s/]+$/.test(repo)) {
_hideGgufPicker();
return false;
}
dlGgufRow.style.display = 'flex';
dlGgufQuant.innerHTML = '<option value="">Scanning...</option>';
dlGgufQuant.dataset.repo = repo;
dlGgufNote.textContent = '';
try {
const res = await fetch(`/api/cookbook/hf-gguf-files?repo_id=${encodeURIComponent(repo)}`, { credentials: 'same-origin' });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
if (!data.ok) throw new Error(data.error || 'scan failed');
if (dlGgufQuant.dataset.repo !== repo) return false;
const files = (data.files || [])
.map(s => String(s || ''))
.filter(name => /\.gguf$/i.test(name));
const byQuant = new Map();
files.forEach(name => {
const quant = _ggufQuantFromPath(name);
if (!quant) return;
if (!byQuant.has(quant)) byQuant.set(quant, []);
byQuant.get(quant).push(name);
});
if (!byQuant.size) {
_hideGgufPicker('No GGUF quants found');
return false;
}
const quantRank = q => {
const m = q.match(/^I?Q(\d)/i);
return m ? Number(m[1]) : 99;View on GitHub (pinned to f9235ebbf1)
Solutions
- Read data.error — it names the upstream reason; fix accordingly (repo spelling, token, back off after rate limit)
- Open the repo page on huggingface.co to confirm it exists and actually contains .gguf files
- For private repos, configure the HF token on the backend
- Retry after a short delay if rate-limited
Defensive patterns
Strategy: fallback
Validate before calling
if (!/^[\w.-]+\/[\w.-]+$/.test(repo)) { dlGgufNote.textContent = 'Not a valid HF repo (owner/name)'; return false; } Try / catch
const data = await res.json();
if (!data.ok) {
const err = data.error || 'scan failed';
if (/rate|429|too many/i.test(err)) { dlGgufNote.textContent = 'Hugging Face rate limit — retry in a moment'; return false; }
if (/not found|404/i.test(err)) { dlGgufNote.textContent = 'Repo not found or has no GGUF files'; return false; }
throw new Error(err);
} Prevention
- Show data.error in dlGgufNote instead of a generic string — it names the upstream cause
- Cache successful scans per repo so repeat selections don't re-hit the HF API
- Handle 'no gguf files' as an informational state, not an error
When it happens
Trigger: Backend responds 200 with {ok:false,error:'repo not found' | 'rate limited' | 'no network'}; repo exists but has zero .gguf files so files comes back empty; HF API token invalid/expired causing upstream 401 mapped to ok:false.
Common situations: Typo'd or renamed HF repo; private/gated repo without a configured token; HF rate limiting after repeated scans; repo hosts only safetensors so no GGUF quants are found.
Related errors
- HTTP ${res.status}
- HTTP ${res.status} ${res.statusText}${msg ? `: ${msg}` : ''}
- data.detail || data.error || `HTTP ${res.status}`
- data.error || 'Failed to generate SSH key'
- HTTP ${res.status}
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/32da82f591f3a7ee.
Report an issue: GitHub.