{"record":{"id":"32da82f591f3a7ee","repo":"odysseus-dev/odysseus","slug":"data-error-scan-failed","errorCode":null,"errorMessage":"data.error || 'scan failed'","messagePattern":"data\\.error \\|\\| 'scan failed'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"static/js/cookbook.js","lineNumber":2406,"sourceCode":"      if (!dlGgufRow || !dlGgufQuant || !dlGgufNote) return false;\n      const rawRepo = _stripHfUrl(rawValue || '');\n      const ollamaName = _ollamaName(rawRepo);\n      const fileSplit = !ollamaName ? _splitRepoFile(rawRepo) : null;\n      const split = ollamaName ? { repo: ollamaName, include: null } : (fileSplit || _splitRepoTag(rawRepo));\n      const repo = split.repo || '';\n      if (ollamaName || split.include || !/^[^\\s/]+\\/[^\\s/]+$/.test(repo)) {\n        _hideGgufPicker();\n        return false;\n      }\n      dlGgufRow.style.display = 'flex';\n      dlGgufQuant.innerHTML = '<option value=\"\">Scanning...</option>';\n      dlGgufQuant.dataset.repo = repo;\n      dlGgufNote.textContent = '';\n      try {\n        const res = await fetch(`/api/cookbook/hf-gguf-files?repo_id=${encodeURIComponent(repo)}`, { credentials: 'same-origin' });\n        if (!res.ok) throw new Error(`HTTP ${res.status}`);\n        const data = await res.json();\n        if (!data.ok) throw new Error(data.error || 'scan failed');\n        if (dlGgufQuant.dataset.repo !== repo) return false;\n        const files = (data.files || [])\n          .map(s => String(s || ''))\n          .filter(name => /\\.gguf$/i.test(name));\n        const byQuant = new Map();\n        files.forEach(name => {\n          const quant = _ggufQuantFromPath(name);\n          if (!quant) return;\n          if (!byQuant.has(quant)) byQuant.set(quant, []);\n          byQuant.get(quant).push(name);\n        });\n        if (!byQuant.size) {\n          _hideGgufPicker('No GGUF quants found');\n          return false;\n        }\n        const quantRank = q => {\n          const m = q.match(/^I?Q(\\d)/i);\n          return m ? Number(m[1]) : 99;","sourceCodeStart":2388,"sourceCodeEnd":2424,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/cookbook.js#L2388-L2424","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if (!/^[\\w.-]+\\/[\\w.-]+$/.test(repo)) { dlGgufNote.textContent = 'Not a valid HF repo (owner/name)'; return false; }","typeGuard":null,"tryCatchPattern":"const data = await res.json();\nif (!data.ok) {\n  const err = data.error || 'scan failed';\n  if (/rate|429|too many/i.test(err)) { dlGgufNote.textContent = 'Hugging Face rate limit — retry in a moment'; return false; }\n  if (/not found|404/i.test(err)) { dlGgufNote.textContent = 'Repo not found or has no GGUF files'; return false; }\n  throw new Error(err);\n}","preventionTips":["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"],"tags":["fetch","huggingface","gguf","application-error","cookbook"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}