{"record":{"id":"f7ef78112f52cb73","repo":"Kareadita/Kavita","slug":"send-to-size-limit","errorCode":null,"errorMessage":"send-to-size-limit","messagePattern":"send-to-size-limit","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"error","filePath":"Kavita.Services/DeviceService.cs","lineNumber":115,"sourceCode":"        return false;\n    }\n\n    public async Task<bool> SendTo(IReadOnlyList<int> chapterIds, int deviceId, CancellationToken ct = default)\n    {\n        var settings = await unitOfWork.SettingsRepository.GetSettingsDtoAsync(ct);\n        if (!settings.IsEmailSetupForSendToDevice())\n            throw new KavitaException(\"send-to-kavita-email\");\n\n        var device = await unitOfWork.DeviceRepository.GetDeviceById(deviceId, ct);\n        if (device == null) throw new KavitaException(\"device-doesnt-exist\");\n\n        var files = await unitOfWork.ChapterRepository.GetFilesForChaptersAsync(chapterIds, ct);\n        if (files.Any(f => f.Format is not (MangaFormat.Epub or MangaFormat.Pdf)) && device.Platform == EmailDevicePlatform.Kindle)\n            throw new KavitaException(\"send-to-permission\");\n\n        // If the size of the files is too big\n        if (files.Sum(f => f.Bytes) >= settings.SmtpConfig.SizeLimit)\n            throw new KavitaException(\"send-to-size-limit\");\n\n\n        try\n        {\n            device.UpdateLastUsed();\n            unitOfWork.DeviceRepository.Update(device);\n            await unitOfWork.CommitAsync(ct);\n        }\n        catch (Exception ex)\n        {\n            logger.LogError(ex, \"There was an issue updating device last used time\");\n        }\n\n        var success = await emailService.SendFilesToEmail(new SendToDto()\n        {\n            UserId = device.AppUserId,\n            DestinationEmail = device.EmailAddress!,\n            FilePaths = files.Select(m => m.FilePath)","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/DeviceService.cs#L97-L133","documentation":"Thrown by DeviceService.SendTo when the combined byte size of all selected files meets or exceeds settings.SmtpConfig.SizeLimit. The check uses files.Sum(f => f.Bytes) >= SizeLimit, so hitting the exact limit also triggers it. This prevents sending oversized email attachments that the SMTP server would reject.","triggerScenarios":"User selects too many chapters or very large files (high-resolution PDFs, large epubs with embedded images) whose total exceeds the SMTP size limit; the SizeLimit is configured too low for the user's content.","commonSituations":"Sending a full volume of high-resolution manga to a device; SMTP provider has a strict attachment size cap (e.g., Gmail's 25MB limit); user hasn't adjusted the default SizeLimit to match their SMTP provider's actual cap.","solutions":["Select fewer chapters or smaller files to stay under the size limit","Increase the SmtpConfig.SizeLimit in Server Settings to match the SMTP provider's maximum (verify the provider supports larger attachments)","Split the send into multiple smaller batches, each under the limit","Consider compressing or downsampling large files before adding them to the library"],"exampleFix":"// Before calling SendTo, check total size client-side:\n// const totalBytes = selectedFiles.reduce((sum, f) => sum + f.bytes, 0);\n// if (totalBytes >= smtpSizeLimit) {\n//   toast.error(`Total size ${formatBytes(totalBytes)} exceeds limit ${formatBytes(smtpSizeLimit)}. Remove some files.`);\n//   return;\n// }","handlingStrategy":"validation","validationCode":"// Check total size before calling SendTo:\n// var files = await unitOfWork.ChapterRepository.GetFilesForChaptersAsync(chapterIds, ct);\n// var settings = await unitOfWork.SettingsRepository.GetSettingsDtoAsync(ct);\n// var totalBytes = files.Sum(f => f.Bytes);\n// if (totalBytes >= settings.SmtpConfig.SizeLimit) {\n//     return BadRequest($\"Total size ({totalBytes / 1024 / 1024}MB) exceeds the limit ({settings.SmtpConfig.SizeLimit / 1024 / 1024}MB)\");\n// }","typeGuard":null,"tryCatchPattern":"// try {\n//     await deviceService.SendTo(chapterIds, deviceId, ct);\n// } catch (KavitaException ex) when (ex.Message == \"send-to-size-limit\") {\n//     return BadRequest(new { error = \"Total file size exceeds the SMTP size limit. Remove some files or increase the limit in settings.\" });\n// }","preventionTips":["Display a running total of selected file sizes against the SMTP size limit in the UI","Set the SMTP SizeLimit to match the provider's actual maximum (e.g., 25MB for Gmail)","Guide users to send in smaller batches when the total exceeds the limit"],"tags":["device","email","size-limit","smtp","send-to-device","attachment"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}