{"record":{"id":"69225cb418ba95e7","repo":"odysseus-dev/odysseus","slug":"d-error-clear-failed","errorCode":null,"errorMessage":"d.error || 'Clear failed'","messagePattern":"d\\.error \\|\\| 'Clear failed'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"static/js/gallery.js","lineNumber":2420,"sourceCode":"  }\n\n  // ── Clear AI Tags ──\n  const clearAiTagsBtn = document.getElementById('gallery-clear-ai-tags-btn');\n  if (clearAiTagsBtn) {\n    clearAiTagsBtn.addEventListener('click', async () => {\n      if (clearAiTagsBtn.disabled) return;\n      if (moreMenu) { moreMenu.hidden = true; moreMenu.style.display = 'none'; }\n      if (!await uiModule.styledConfirm(\n        'Remove all AI-generated tags from every photo? Your own tags are kept.',\n        { confirmText: 'Clear AI Tags', danger: true }\n      )) return;\n      clearAiTagsBtn.disabled = true;\n      try {\n        const r = await fetch(`${API_BASE}/api/gallery/clear-ai-tags`, {\n          method: 'POST', credentials: 'same-origin',\n        });\n        const d = await r.json();\n        if (!d.ok) throw new Error(d.error || 'Clear failed');\n        uiModule.showToast(`Cleared AI tags on ${d.cleared} photo${d.cleared === 1 ? '' : 's'}`);\n        await _fetchLibrary(false);\n      } catch (e) {\n        uiModule.showError(`Failed to clear AI tags: ${e.message || e}`);\n      } finally {\n        clearAiTagsBtn.disabled = false;\n      }\n    });\n  }\n\n\n  // ── Select mode + bulk delete ──\n  let _selectMode = false;\n  const selectBtn = document.getElementById('gallery-select-btn');\n  const bulkBar = document.getElementById('gallery-bulk-bar');\n\n  const _selectedDots = () => [...document.querySelectorAll('.gallery-select-dot.selected')];\n  const _selectedIds = () => _selectedDots().map(d => d.closest('.gallery-card')?.dataset.id).filter(Boolean);","sourceCodeStart":2402,"sourceCodeEnd":2438,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/gallery.js#L2402-L2438","documentation":"Thrown by gallery.js after POST /api/gallery/clear-ai-tags returns JSON with ok !== true. The server responded (r.json() succeeded) but explicitly reported failure, with an optional error string; the client falls back to the generic 'Clear failed' when the body omits it. The catch shows a toast-style showError and re-enables the button in finally.","triggerScenarios":"Tapping 'Clear AI Tags' in the gallery more-menu while the backend photo index or AI-tag store is unavailable; a partially migrated database where photos exist but ai_tags metadata table is locked or missing; server returns 200 with {ok:false, error:'...'} after an internal partial failure.","commonSituations":"Photo library scanned but AI tag job never ran or was interrupted; database locked by a concurrent indexing job; backend version mismatch where the endpoint exists but its worker dependency (tag store) failed to initialize.","solutions":["Retry the action once the gallery finishes any in-progress indexing (wait for scans to settle).","Check backend logs for the error string the server attached to {ok:false}.","If the error persists, verify the ai-tags store/table exists and is writable in the backend data directory.","As a last resort, re-run the AI tagging pipeline then clear again."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"const isClearResult = (d) => d && typeof d.ok === 'boolean';","tryCatchPattern":"try { const d = await r.json(); if (!isClearResult(d) || !d.ok) throw new Error(d.error || 'Clear failed'); } catch (e) { uiModule.showError(`Failed to clear AI tags: ${e.message || e}`); } finally { clearAiTagsBtn.disabled = false; }","preventionTips":["Keep the confirm dialog before destructive bulk actions","Always re-enable the button in finally so one failure cannot brick the control","Log server error strings for diagnosis"],"tags":["gallery","api","ai-tags","frontend"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}