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

  1. Set totalBackups to an integer between 1 and 30 inclusive and resend the request.
  2. Add client-side range validation (1..30) on the backups field and disable submit while invalid.
  3. Re-GET /api/settings to read the current value and reconcile the form before saving.
  4. 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

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


AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13). Data as JSON: /api/errors/9b435b60550f799d. Report an issue: GitHub.