SillyTavern/SillyTavern · error · Error
Theme could not be saved
Error message
Theme could not be saved
What it means
Thrown after POST /api/themes/save returns a non-ok HTTP response. The handler already fires a toastr error and console.error with the response object, then re-throws so callers know the save failed. It signals a server-side or transport failure, not a validation problem with the theme itself.
Source
Thrown at public/scripts/power-user.js:2508
}
name = await getSanitizedFilename(String(newName));
}
if (typeof theme !== 'object') {
theme = getThemeObject(name);
}
const response = await fetch('/api/themes/save', {
method: 'POST',
headers: getRequestHeaders(),
body: JSON.stringify(theme),
});
if (!response.ok) {
toastr.error('Check the server connection and reload the page to prevent data loss.', 'Theme could not be saved');
console.error('Theme could not be saved', response);
throw new Error('Theme could not be saved');
}
const themeIndex = themes.findIndex(x => x.name == name);
if (themeIndex == -1) {
themes.push(theme);
const option = document.createElement('option');
option.selected = true;
option.value = name;
option.innerText = name;
$('#themes').append(option);
} else {
themes[themeIndex] = theme;
$(`#themes option[value="${name}"]`).prop('selected', true);
}
power_user.theme = name;
saveSettingsDebounced();View on GitHub (pinned to 8172dcd0ee)
Solutions
- Reload the page to refresh session/auth tokens, then retry the save.
- Confirm the server process is running and reachable (server logs, health endpoint).
- Inspect response.status and the response body in the DevTools Network tab for the specific failure code.
- If the CSS is large, check server/proxy max-body-size and timeout limits.
Defensive patterns
Strategy: retry
Validate before calling
// Best-effort connectivity check before saving.
async function serverReachable() {
try {
const r = await fetch('/api/ping', { method: 'HEAD' });
return r.ok;
} catch { return false; }
} Try / catch
// Retry transient failures a few times, then surface a clear message.
async function saveThemeSafe(name, theme, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try {
return await saveTheme(name, theme);
} catch (e) {
if (e.message !== 'Theme could not be saved' || i === attempts - 1) throw e;
await new Promise(r => setTimeout(r, 500 * (i + 1)));
}
}
} Prevention
- Prompt the user to reload the page after long idle periods to refresh auth tokens.
- Show an unsaved-changes indicator so a failed save is not silently lost.
- Watch the Network tab for 401/403/500 on /api/themes/save to distinguish auth vs server faults.
When it happens
Trigger: saveTheme(name, theme) is invoked (theme dropdown change, new theme creation, CSS edit) while the server is unreachable, returns 4xx/5xx, or the session/auth has expired.
Common situations: Backend process stopped, network drop, expired CSRF/session token, full disk on the server, reverse-proxy body-size limit exceeded by large CSS, or a server restart lost in-memory state.
Related errors
- Preset could not be saved
- Preset could not be renamed
- Invalid argument for unnamed argument provided. This is not
- Captioning videos is not supported for the current source.
- No captioning module is available.
AI-assisted analysis of SillyTavern/SillyTavern@8172dcd0ee (2026-08-13).
Data as JSON: /api/errors/a5e1bb40498a5afc.
Report an issue: GitHub.