{"record":{"id":"a44684d54bf295db","repo":"odysseus-dev/odysseus","slug":"await-res-text-a44684","errorCode":null,"errorMessage":"await res.text()","messagePattern":"await res\\.text\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"static/js/rag.js","lineNumber":97,"sourceCode":"    });\n  } catch (e) {\n    console.error(e);\n    box.innerHTML = '';\n    const error = document.createElement('div');\n    error.textContent = 'Failed to load files';\n    error.style.color = 'var(--color-error)';\n    box.appendChild(error);\n  }\n}\n\nasync function _deleteFile(filepath, displayName) {\n  if (!await uiModule.styledConfirm(`Remove \"${displayName}\" from RAG?`, { confirmText: 'Remove', danger: true })) return;\n  try {\n    const res = await fetch(`${API_BASE}/api/personal/file?filepath=${encodeURIComponent(filepath)}`, {\n      method: 'DELETE',\n      credentials: 'same-origin'\n    });\n    if (!res.ok) throw new Error(await res.text());\n    await loadPersonalDocs();\n  } catch (e) {\n    console.error('Delete failed:', e);\n    alert('Failed to delete file: ' + e.message);\n  }\n}\n\n/**\n * Upload files to RAG\n */\nexport async function uploadRagFiles(fileList) {\n  if (!fileList || !fileList.length) return;\n\n  const zone = document.getElementById('rag-upload-zone');\n  if (zone) zone.textContent = 'Uploading…';\n\n  const fd = new FormData();\n  for (const file of fileList) {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/rag.js#L79-L115","documentation":"Thrown by _deleteFile in rag.js when DELETE /api/personal/file?filepath=... returns non-ok; the raw response text becomes the Error message. Because the body is not JSON-parsed, server detail strings or full HTML error pages can appear verbatim in the alert('Failed to delete file: ' + e.message).","triggerScenarios":"Removing a RAG document whose file was already deleted from disk (404/500 with traceback text); filepath query param encoding a path outside the personal docs root being rejected; vector store still indexing the doc so delete is refused.","commonSituations":"Files removed manually on disk while indexed in the vector store; concurrent uploads/deletes racing; path traversal protection rejecting legitimately odd filenames.","solutions":["Refresh the personal docs list (loadPersonalDocs) and retry delete on the current entry.","Check the response text shown in the alert — it names the server-side reason.","If the store is mid-index, wait for ingestion to finish then delete.","For stubborn entries, re-run the store's cleanup/reindex routine server-side."],"exampleFix":"// before\nif (!res.ok) throw new Error(await res.text());\n\n// after\nif (!res.ok) {\n  const body = await res.json().catch(() => null);\n  throw new Error(body?.detail || `HTTP ${res.status}`);\n}","handlingStrategy":"try-catch","validationCode":"if (!filepath || filepath.includes('..')) { toast('Invalid file path'); return; }","typeGuard":null,"tryCatchPattern":"try { if (!res.ok) { const b = await res.json().catch(() => null); throw new Error(b?.detail || `HTTP ${res.status}`); } await loadPersonalDocs(); } catch (e) { alert('Failed to delete file: ' + e.message); }","preventionTips":["Parse JSON error bodies instead of raw text to avoid HTML-in-alert","Refresh the doc list after every delete attempt","Treat 404 deletes as success"],"tags":["rag","delete","http","vector-store"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}