odysseus-dev/odysseus · warning · Error
d.error || 'Clear failed'
Error message
d.error || 'Clear failed'
What it means
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.
Source
Thrown at static/js/gallery.js:2420
}
// ── Clear AI Tags ──
const clearAiTagsBtn = document.getElementById('gallery-clear-ai-tags-btn');
if (clearAiTagsBtn) {
clearAiTagsBtn.addEventListener('click', async () => {
if (clearAiTagsBtn.disabled) return;
if (moreMenu) { moreMenu.hidden = true; moreMenu.style.display = 'none'; }
if (!await uiModule.styledConfirm(
'Remove all AI-generated tags from every photo? Your own tags are kept.',
{ confirmText: 'Clear AI Tags', danger: true }
)) return;
clearAiTagsBtn.disabled = true;
try {
const r = await fetch(`${API_BASE}/api/gallery/clear-ai-tags`, {
method: 'POST', credentials: 'same-origin',
});
const d = await r.json();
if (!d.ok) throw new Error(d.error || 'Clear failed');
uiModule.showToast(`Cleared AI tags on ${d.cleared} photo${d.cleared === 1 ? '' : 's'}`);
await _fetchLibrary(false);
} catch (e) {
uiModule.showError(`Failed to clear AI tags: ${e.message || e}`);
} finally {
clearAiTagsBtn.disabled = false;
}
});
}
// ── Select mode + bulk delete ──
let _selectMode = false;
const selectBtn = document.getElementById('gallery-select-btn');
const bulkBar = document.getElementById('gallery-bulk-bar');
const _selectedDots = () => [...document.querySelectorAll('.gallery-select-dot.selected')];
const _selectedIds = () => _selectedDots().map(d => d.closest('.gallery-card')?.dataset.id).filter(Boolean);View on GitHub (pinned to f9235ebbf1)
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.
Defensive patterns
Strategy: try-catch
Type guard
const isClearResult = (d) => d && typeof d.ok === 'boolean';
Try / catch
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; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- detail || ('HTTP ' + res.status)
- HTTP ${resp.status}${detail ? `: ${detail}` : ''}
- HTTP ${saveRes.status}: ${errBody.substring(0, 120)}
- Failed to save note
- Revoke failed
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/69225cb418ba95e7.
Report an issue: GitHub.