{"record":{"id":"efd547cfa0839c92","repo":"Kareadita/Kavita","slug":"total-logs","errorCode":"total-logs","errorMessage":"total-logs","messagePattern":"total-logs","errorType":"exception","errorClass":"KavitaException","httpStatus":400,"severity":"warning","filePath":"Kavita.Services/SettingsService.cs","lineNumber":457,"sourceCode":"\n            if (setting.Key == ServerSettingKey.TotalBackups &&\n                updateSettingsDto.TotalBackups + string.Empty != setting.Value)\n            {\n                if (updateSettingsDto.TotalBackups > 30 || updateSettingsDto.TotalBackups < 1)\n                {\n                    throw new KavitaException(\"total-backups\");\n                }\n\n                setting.Value = updateSettingsDto.TotalBackups + string.Empty;\n                unitOfWork.SettingsRepository.Update(setting);\n            }\n\n            if (setting.Key == ServerSettingKey.TotalLogs &&\n                updateSettingsDto.TotalLogs + string.Empty != setting.Value)\n            {\n                if (updateSettingsDto.TotalLogs > 30 || updateSettingsDto.TotalLogs < 1)\n                {\n                    throw new KavitaException(\"total-logs\");\n                }\n\n                setting.Value = updateSettingsDto.TotalLogs + string.Empty;\n                unitOfWork.SettingsRepository.Update(setting);\n            }\n\n            if (setting.Key == ServerSettingKey.EnableFolderWatching &&\n                updateSettingsDto.EnableFolderWatching + string.Empty != setting.Value)\n            {\n                setting.Value = updateSettingsDto.EnableFolderWatching + string.Empty;\n                unitOfWork.SettingsRepository.Update(setting);\n            }\n        }\n\n        if (!unitOfWork.HasChanges()) return updateSettingsDto;\n\n        try\n        {","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/SettingsService.cs#L439-L475","documentation":"Range-validation error for the 'Total Logs' server setting, the number of days of log files Kavita keeps before cleanup. Identical in shape to the backups guard: the SettingsService throws KavitaException('total-logs') when TotalLogs is < 1 or > 30, again only when the value is changing. SettingsController maps it to HTTP 400 'Total Logs must be between 1 and 30'.","triggerScenarios":"POST /api/settings with totalLogs set to 0, negative, or greater than 30, where the value differs from the persisted setting.","commonSituations":"Admin sets 0 to 'disable logging retention'; very large value expecting indefinite log storage; default DTO has no initializer for TotalLogs so a malformed payload can post an out-of-range int; migrating settings from a version with different bounds.","solutions":["Set totalLogs to an integer between 1 and 30 inclusive and resend.","Add client-side range validation (1..30) mirroring the backups field.","Re-GET /api/settings to load the current value before editing.","For scripted config, clamp the value into [1, 30] before posting."],"exampleFix":"// before\n{ totalLogs: 365 } // 'keep a year'\n\n// after\n{ totalLogs: 30 } // valid: 1..30","handlingStrategy":"validation","validationCode":"// Run before POST /api/settings\nfunction isValidRetention(n: unknown): n is number {\n  return typeof n === 'number' && Number.isInteger(n) && n >= 1 && n <= 30;\n}\nif (!isValidRetention(dto.totalLogs)) {\n  showError('Total Logs must be between 1 and 30');\n  return;\n}","typeGuard":"function isValidRetention(n: unknown): n is number {\n  return typeof n === 'number' && Number.isInteger(n) && n >= 1 && n <= 30;\n}","tryCatchPattern":null,"preventionTips":["Clamp the logs input to [1, 30] in the UI stepper.","Default the form field to 30 (the seeded value) so it is never submitted empty/0.","Keep client bounds identical to the server's 1..30 to avoid mismatched messaging."],"tags":["settings","validation","logs","range","admin"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}