{"record":{"id":"a51840a72326c992","repo":"odysseus-dev/odysseus","slug":"document-create-failed-http-res-status","errorCode":null,"errorMessage":"Document create failed: HTTP ${res.status}","messagePattern":"Document create failed: HTTP (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"static/js/document.js","lineNumber":7044,"sourceCode":"    if (_creatingDoc) return;\n    _creatingDoc = true;\n    // If the panel was in empty-state, the user may type into the editor\n    // during the create round-trip — preserve that text into the new doc\n    // instead of letting switchToDoc blank it.\n    const wasEmpty = !activeDocId;\n    try {\n      const res = await fetch(`${API_BASE}/api/document`, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        credentials: 'same-origin',\n        body: JSON.stringify({\n          session_id: sessionId,\n          title: '',\n          content: '',\n          language: 'markdown',\n        }),\n      });\n      if (!res.ok) throw new Error(`Document create failed: HTTP ${res.status}`);\n      const doc = await res.json();\n      if (!doc || !doc.id) throw new Error('Document create failed: missing id');\n      addDocToTabs(doc, sessionId);\n      if (!isOpen) openPanel();\n      // Re-enable editor if it was in empty state\n      let textarea = document.getElementById('doc-editor-textarea');\n      if (textarea) {\n        textarea.disabled = false;\n        textarea.placeholder = 'Document content...';\n      }\n      // Capture text typed during the round-trip (only when starting from the\n      // empty editor — don't steal another doc's content).\n      const typed = (wasEmpty && textarea && textarea.value.trim()) ? textarea.value : '';\n      switchToDoc(doc.id);\n      if (typed) {\n        textarea = document.getElementById('doc-editor-textarea');\n        if (textarea) textarea.value = typed;\n        const d = docs.get(doc.id);","sourceCodeStart":7026,"sourceCodeEnd":7062,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/document.js#L7026-L7062","documentation":"Thrown in static/js/document.js when POST /api/document (creating a new empty markdown doc, e.g. from the empty-editor bootstrap path) returns non-2xx. The template literal `Document create failed: HTTP ${res.status}` records only the status; the response body (which FastAPI-style backends use for detail) is discarded.","triggerScenarios":"Typing into a fresh, empty editor which triggers creation with session_id; backend rejects because session_id is invalid/unknown (400/422), auth expired (401), or a server error (500) while inserting the row.","commonSituations":"Session id from a stale _lastSessionId after server restart wiped sessions; database locked or migration pending; deploy where POST /api/document gained required fields the frontend doesn't send.","solutions":["Check the response body of the failed POST for a detail message — it usually names the missing/invalid field.","Confirm sessionId is a live session (GET the session or create one first).","If 422, diff the backend's DocumentCreate schema against the sent body {session_id, title, content, language}.","Include the body in the thrown message for future diagnosability."],"exampleFix":"// before\nif (!res.ok) throw new Error(`Document create failed: HTTP ${res.status}`);\n\n// after\nif (!res.ok) {\n  let detail = '';\n  try { const j = await res.json(); detail = j?.detail || j?.error || ''; } catch (_) {}\n  throw new Error(`Document create failed: HTTP ${res.status}${detail ? ` — ${detail}` : ''}`);\n}","handlingStrategy":"try-catch","validationCode":"const sessionId = sessionModule?.getCurrentSessionId?.() || _lastSessionId;\nif (!sessionId) { /* create/await a session first */ }","typeGuard":"function isCreatedDoc(doc) {\n  return doc != null && typeof doc === 'object' && (typeof doc.id === 'string' || typeof doc.id === 'number');\n}","tryCatchPattern":"try {\n  const res = await fetch(`${API_BASE}/api/document`, { /* ... */ });\n  let body = null;\n  try { body = await res.json(); } catch (_) {}\n  if (!res.ok) throw new Error(`Document create failed: HTTP ${res.status}${body?.detail ? ' — ' + body.detail : ''}`);\n  if (!isCreatedDoc(body)) throw new Error('Document create failed: missing id');\n} catch (e) {\n  if (uiModule) uiModule.showError(`Could not create document: ${e.message}`);\n}","preventionTips":["Ensure a valid session exists before the empty-editor bootstrap triggers a create.","Include the parsed detail in the message so 422s self-explain.","Keep a typed schema for POST /api/document's response and validate it in one place."],"tags":["http","document-create","api-error","bootstrap"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}