{"record":{"id":"f1202a5124c4c858","repo":"odysseus-dev/odysseus","slug":"http-res-status-res-statustext-msg-m-f1202a","errorCode":null,"errorMessage":"HTTP ${res.status} ${res.statusText}${msg ? `: ${msg}` : ''}","messagePattern":"HTTP (.+?) (.+?)(.+?)` : ''\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"static/js/cookbookServe.js","lineNumber":4213,"sourceCode":"      setTimeout(() => {\n        if (list.querySelector('.serve-empty-auto-scan')) _fetchCachedModels(true);\n      }, 60);\n      const tagContainer = document.getElementById('serve-tags');\n      if (tagContainer) tagContainer.innerHTML = '';\n      return;\n    }\n    const res = await fetch(`/api/model/cached${params}`);\n    if (!res.ok) {\n      const body = await res.text().catch(() => '');\n      let msg = '';\n      try {\n        const payload = JSON.parse(body);\n        msg = payload && (payload.detail || payload.error || payload.message);\n      } catch {\n        msg = body;\n      }\n      msg = typeof msg === 'string' ? msg.trim() : '';\n      throw new Error(`HTTP ${res.status} ${res.statusText}${msg ? `: ${msg}` : ''}`);\n    }\n    const data = await res.json();\n    if (data && data.error) throw new Error(data.error);\n    _writeCachedModelScan(scanSig, data);\n    _dlWp.destroy();\n    _renderCachedModelsData(list, data, host);\n  } catch (e) {\n    _dlWp.destroy();\n    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>`;\n    list.querySelector('.serve-empty-scan-btn')?.addEventListener('click', () => {\n      _fetchCachedModels(true);\n    });\n  }\n}\n\n/** Filter presets matching a model repo */\nfunction _presetsForModel(presets, repo) {\n  const short = repo.split('/').pop();","sourceCodeStart":4195,"sourceCodeEnd":4231,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/cookbookServe.js#L4195-L4231","documentation":"Error thrown when the cached-model scan for the serve panel fails at the HTTP level: GET /api/model/cached<params> answered non-OK. The handler reads the body text, tries JSON detail/error/message, and appends whatever it found to the status line, then renders a 'Cached model scan failed' panel with a Retry button.","triggerScenarios":"GET /api/model/cached returns 500 (backend scan of the models directory crashed — permission denied, disk error, huge directory timeout), 502/504 behind a proxy, or the scan is pointed at a remote host via params whose SSH connection failed.","commonSituations":"Models directory on a network mount that dropped; scan of a remote cache host whose SSH credentials changed; response body too large/slow triggering gateway timeout; backend updated and the route contract moved.","solutions":["Use the Retry button after fixing the underlying cause identified in the ': <msg>' suffix","curl -i the same /api/model/cached URL with params to see the full body","Verify filesystem permissions on the models cache directory (and SSH reachability if host-scoped)","Check backend logs for the scan exception"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(`/api/model/cached${params}`);\n  if (!res.ok) {\n    const body = await res.text().catch(() => '');\n    let msg = '';\n    try { msg = JSON.parse(body)?.detail || ''; } catch { msg = body; }\n    throw new Error(`HTTP ${res.status} ${res.statusText}${msg ? ': ' + String(msg).trim().slice(0, 200) : ''}`);\n  }\n  const data = await res.json();\n  if (data?.error) throw new Error(data.error);\n  _writeCachedModelScan(scanSig, data);\n  _dlWp.destroy();\n  _renderCachedModelsData(list, data, host);\n} catch (e) {\n  _dlWp.destroy();\n  renderScanFailureWithRetry(list, e.message, () => _fetchCachedModels(true));\n}","preventionTips":["Keep the Retry button wired (already present) and cap auto-retries to one","Cache successful scans (the _writeCachedModelScan pattern) so transient failures don't blank the panel","Scope the request with a timeout; large directories can hang proxies"],"tags":["fetch","http-error","model-cache","scan","serve"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}