Kareadita/Kavita · warning · KavitaException
total-backups
total-backups
Error message
total-backups
What it means
Range-validation error for the 'Total Backups' server setting. Kavita retains at most 30 backup snapshots (CleanupService reads this value as the day/file threshold), so the SettingsService rejects any retention count outside [1, 30]. It is thrown as a KavitaException with the localization key 'total-backups' while iterating server settings, only when the submitted value actually differs from the stored one. SettingsController catches it and returns HTTP 400 with the translated message 'Total Backups must be between 1 and 30'.
Source
Thrown at Kavita.Services/SettingsService.cs:445
setting.Value = directoryService.FileSystem.Path.GetFullPath(bookmarkDirectory);
unitOfWork.SettingsRepository.Update(setting);
updateBookmarks = true;
}
if (setting.Key == ServerSettingKey.AllowStatCollection &&
updateSettingsDto.AllowStatCollection + string.Empty != setting.Value)
{
setting.Value = updateSettingsDto.AllowStatCollection + string.Empty;
unitOfWork.SettingsRepository.Update(setting);
}
if (setting.Key == ServerSettingKey.TotalBackups &&
updateSettingsDto.TotalBackups + string.Empty != setting.Value)
{
if (updateSettingsDto.TotalBackups > 30 || updateSettingsDto.TotalBackups < 1)
{
throw new KavitaException("total-backups");
}
setting.Value = updateSettingsDto.TotalBackups + string.Empty;
unitOfWork.SettingsRepository.Update(setting);
}
if (setting.Key == ServerSettingKey.TotalLogs &&
updateSettingsDto.TotalLogs + string.Empty != setting.Value)
{
if (updateSettingsDto.TotalLogs > 30 || updateSettingsDto.TotalLogs < 1)
{
throw new KavitaException("total-logs");
}
setting.Value = updateSettingsDto.TotalLogs + string.Empty;
unitOfWork.SettingsRepository.Update(setting);
}
View on GitHub (pinned to 9c3e540000)
Solutions
- Set totalBackups to an integer between 1 and 30 inclusive and resend the request.
- Add client-side range validation (1..30) on the backups field and disable submit while invalid.
- Re-GET /api/settings to read the current value and reconcile the form before saving.
- If automating config import, clamp the imported value into [1, 30] before posting.
Example fix
// before
{ totalBackups: 0 } // 'keep no backups'
// after
{ totalBackups: 7 } // valid: 1..30 Defensive patterns
Strategy: validation
Validate before calling
// Run before POST /api/settings
function isValidRetention(n: unknown): n is number {
return typeof n === 'number' && Number.isInteger(n) && n >= 1 && n <= 30;
}
if (!isValidRetention(dto.totalBackups)) {
showError('Total Backups must be between 1 and 30');
return; // do not call the API
} Type guard
function isValidRetention(n: unknown): n is number {
return typeof n === 'number' && Number.isInteger(n) && n >= 1 && n <= 30;
} Prevention
- Bind the backups input to a number stepper clamped to [1, 30] and disable save while invalid.
- Mirror the exact server bounds (1..30) in client validation so messages match.
- On any 400 with 'total-backups', re-GET settings and re-sync the form.
When it happens
Trigger: POST /api/settings with totalBackups set to 0, a negative number, or a value greater than 30, where the value differs from the currently persisted setting (the guard is skipped if the value is unchanged).
Common situations: Admin enters 0 intending 'no backups'; admin enters a large number (e.g. 100) expecting unlimited retention; restoring/importing a config blob from another instance whose value was outside the allowed range; a UI form default of 0 slipping through unvalidated.
Related errors
- total-logs
- oidc-invalid-authority
- errors.import-fields.non-unique-age-ratings
- errors.import-fields.non-unique-fields
- ip-address-invalid
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/9b435b60550f799d.
Report an issue: GitHub.