{"record":{"id":"8a80d2da0e353260","repo":"Kareadita/Kavita","slug":"send-to-permission","errorCode":null,"errorMessage":"send-to-permission","messagePattern":"send-to-permission","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"error","filePath":"Kavita.Services/DeviceService.cs","lineNumber":111,"sourceCode":"        {\n            logger.LogError(ex, \"There was an issue with deleting the device, {DeviceId} for user {UserName}\", deviceId, userWithDevices.UserName);\n        }\n\n        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()","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/DeviceService.cs#L93-L129","documentation":"Thrown by DeviceService.SendTo when the selected files include a format other than Epub or Pdf AND the target device platform is Kindle. Kindle devices only accept epub and pdf files via email delivery; sending archives (CBZ, CBR, ZIP) or images to a Kindle is rejected by this guard.","triggerScenarios":"User selects chapters containing CBZ/CBR archives or image formats and sends them to a Kindle device; a mixed-format selection includes at least one non-epub/non-pdf file with a Kindle target.","commonSituations":"User has a manga library in CBZ/CBR format and tries to send to Kindle (Kindle doesn't support comic archives natively); user has mixed-format series and selects all chapters including non-supported formats.","solutions":["Convert the files to EPUB or PDF format before sending to a Kindle device","Select only chapters that are already in EPUB or PDF format when targeting a Kindle","Use a non-Kindle device platform (e.g., a generic email device) that accepts other formats","Set up a conversion pipeline (e.g., KCC - Kindle Comic Converter) to pre-process comic archives"],"exampleFix":"// Filter eligible files before presenting the send-to-device option:\n// var eligibleFiles = files.Where(f =>\n//   device.Platform == EmailDevicePlatform.Kindle\n//     ? f.Format is MangaFormat.Epub or MangaFormat.Pdf\n//     : true\n// ).ToList();\n// if (eligibleFiles.Count < files.Count) {\n//   toast.warn('Some files are not supported on Kindle and were excluded');\n// }","handlingStrategy":"validation","validationCode":"// Filter eligible files before calling SendTo when target is Kindle:\n// var files = await unitOfWork.ChapterRepository.GetFilesForChaptersAsync(chapterIds, ct);\n// var device = await unitOfWork.DeviceRepository.GetDeviceById(deviceId, ct);\n// if (device.Platform == EmailDevicePlatform.Kindle) {\n//     var incompatible = files.Where(f => f.Format is not (MangaFormat.Epub or MangaFormat.Pdf)).ToList();\n//     if (incompatible.Any()) {\n//         return BadRequest($\"Kindle only supports EPUB and PDF. Incompatible files: {string.Join(\", \", incompatible.Select(f => f.FilePath))}\");\n//     }\n// }","typeGuard":null,"tryCatchPattern":"// try {\n//     await deviceService.SendTo(chapterIds, deviceId, ct);\n// } catch (KavitaException ex) when (ex.Message == \"send-to-permission\") {\n//     return BadRequest(new { error = \"Kindle devices only accept EPUB and PDF files. Please select compatible files.\" });\n// }","preventionTips":["Display format compatibility warnings in the UI when a Kindle device is selected","Filter the file selection to show only compatible formats when Kindle is the target","Provide guidance on converting comic archives to EPUB for Kindle delivery"],"tags":["device","kindle","format-restriction","send-to-device","file-format"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}