{"record":{"id":"2031330719f48ee2","repo":"Kareadita/Kavita","slug":"device-doesnt-exist","errorCode":null,"errorMessage":"device-doesnt-exist","messagePattern":"device-doesnt-exist","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"error","filePath":"Kavita.Services/DeviceService.cs","lineNumber":107,"sourceCode":"            if (!unitOfWork.HasChanges()) return true;\n            if (await unitOfWork.CommitAsync(ct)) return true;\n        }\n        catch (Exception ex)\n        {\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        {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/DeviceService.cs#L89-L125","documentation":"Thrown by DeviceService.SendTo when the target device ID is not found in the database via GetDeviceById(deviceId). This is checked after the SMTP configuration check but before file validation. The device lookup is global (not user-scoped in this code path), so any valid device ID in the system passes.","triggerScenarios":"User sends to a device that was deleted; device ID in the request is invalid or from a stale list; the device belongs to a different user and is not found in a scoped query elsewhere.","commonSituations":"Device list is stale in the UI after devices were removed; user bookmarks an old send-to-device link; API client sends a hardcoded device ID that no longer exists.","solutions":["Refresh the device list and select a currently valid device","Verify the device ID exists by calling the list-devices endpoint before sending","Handle the KavitaException and prompt the user to re-select a device"],"exampleFix":"// Validate device exists before calling SendTo:\n// var devices = await deviceService.GetDevicesForUser(userId);\n// if (!devices.Any(d => d.Id == deviceId)) {\n//     return BadRequest('Selected device no longer exists');\n// }","handlingStrategy":"validation","validationCode":"// Verify the device exists before sending:\n// var device = await unitOfWork.DeviceRepository.GetDeviceById(deviceId, ct);\n// if (device == null) return NotFound(\"Device not found\");","typeGuard":null,"tryCatchPattern":"// try {\n//     await deviceService.SendTo(chapterIds, deviceId, ct);\n// } catch (KavitaException ex) when (ex.Message == \"device-doesnt-exist\") {\n//     return NotFound(new { error = \"The selected device no longer exists.\" });\n// }","preventionTips":["Refresh the device list before sending to ensure the device ID is current","Validate the device ID client-side against the active device list","Handle stale device references with clear error messages and a device list refresh prompt"],"tags":["device","not-found","send-to-device"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}