odysseus-dev/odysseus · error · Error
Failed to save
Error message
Failed to save
What it means
Inline settings message shown when saving image-generation settings fails. saveSettings POSTs {image_gen_enabled, image_model, image_quality} to /api/auth/settings; non-OK throws with the response text (or 'HTTP <status>'), and the catch flattens everything to 'Failed to save'.
Source
Thrown at static/js/settings.js:717
const settings = await settingsRes.json();
if (settings.image_model) modelSel.value = settings.image_model;
if (settings.image_quality) qualSel.value = settings.image_quality;
if (enabledToggle) enabledToggle.checked = settings.image_gen_enabled === true;
} catch (e) { console.warn('Failed to load settings', e); }
function syncImgDisabled() {
var off = enabledToggle && !enabledToggle.checked;
var card = enabledToggle ? enabledToggle.closest('.admin-card') : null;
if (card) card.style.opacity = off ? '0.45' : '';
if (configWrap) configWrap.style.pointerEvents = off ? 'none' : '';
}
syncImgDisabled();
async function saveSettings() {
try {
const res = await fetch('/api/auth/settings', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ image_gen_enabled: enabledToggle ? enabledToggle.checked : false, image_model: modelSel.value, image_quality: qualSel.value }) });
if (!res.ok) throw new Error(await res.text().catch(() => `HTTP ${res.status}`));
msg.textContent = 'Saved'; msg.style.color = 'var(--fg)'; setTimeout(() => { msg.textContent = ''; }, 2000);
} catch (e) { msg.textContent = 'Failed to save'; msg.style.color = 'var(--red)'; }
}
modelSel.addEventListener('change', saveSettings);
qualSel.addEventListener('change', saveSettings);
if (enabledToggle) enabledToggle.addEventListener('change', function() { syncImgDisabled(); saveSettings(); });
}
/* ── Vision ── */
async function initVisionSettings() {
const vlSel = el('set-vlModelSelect');
const msg = el('set-visionSettingsMsg');
const enabledToggle = el('set-visionEnabledToggle');
const configWrap = vlSel ? vlSel.closest('div[style*="flex-direction"]') : null;
var _visionEndpoints = [];
var visionFallbackWidget = null;
var _vlExclude = ['audio', 'realtime', 'tts', 'dall-e', 'embedding', 'search', 'whisper'];
function _isVisionModel(mid) {View on GitHub (pinned to f9235ebbf1)
Solutions
- Check devtools for the POST /api/auth/settings status and body
- Re-login / confirm the account has permission to change auth settings
- Verify model and quality values are ones the backend accepts
- Debounce the change-driven autosave and surface e.message instead of a fixed string
Example fix
// before
} catch (e) { msg.textContent = 'Failed to save'; msg.style.color = 'var(--red)'; }
// after
} catch (e) {
console.error('image settings save failed:', e);
msg.textContent = 'Failed to save: ' + e.message;
msg.style.color = 'var(--red)';
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!navigator.onLine) { msg.textContent = 'Offline'; return; }
if (!modelSel.value || !qualSel.value) { msg.textContent = 'Select model and quality'; return; } Try / catch
try { const res = await fetch(...); if (!res.ok) throw new Error(await res.text().catch(() => `HTTP ${res.status}`)); ... } catch (e) { msg.textContent = 'Failed to save: ' + e.message; } Prevention
- Debounce the change-driven autosave so requests don't race
- Confirm the account may call /api/auth/settings
- Surface e.message — the current fixed string hides auth failures
- Disable inputs while a save is pending
When it happens
Trigger: POST /api/auth/settings returns 4xx (unauthenticated, admin-only endpoint, invalid model/quality value) or 5xx; network failure; auto-save fires on 'change' events while a previous save is in flight.
Common situations: Non-admin user opening the settings pane; auth cookie expired so the save silently 401s; choosing a model the backend rejects; rapid consecutive changes racing each other.
Related errors
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/b53692c7464bb8a0.
Report an issue: GitHub.