{"record":{"id":"3ec6dee1e245abe7","repo":"Kareadita/Kavita","slug":"device-not-created","errorCode":null,"errorMessage":"device-not-created","messagePattern":"device-not-created","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"error","filePath":"Kavita.Services/DeviceService.cs","lineNumber":62,"sourceCode":"\n            if (!unitOfWork.HasChanges()) return existingDevice;\n            if (await unitOfWork.CommitAsync(ct)) return existingDevice;\n        }\n        catch (Exception ex)\n        {\n            logger.LogError(ex, \"There was an error when creating your device\");\n            await unitOfWork.RollbackAsync(ct);\n        }\n\n        return null;\n    }\n\n    public async Task<Device?> Update(UpdateEmailDeviceDto dto, AppUser userWithDevices, CancellationToken ct = default)\n    {\n        try\n        {\n            var existingDevice = userWithDevices.Devices.SingleOrDefault(d => d.Id == dto.Id);\n            if (existingDevice == null) throw new KavitaException(\"device-not-created\");\n\n            existingDevice.Name = dto.Name;\n            existingDevice.Platform = dto.Platform;\n            existingDevice.EmailAddress = dto.EmailAddress;\n\n            if (!unitOfWork.HasChanges()) return existingDevice;\n            if (await unitOfWork.CommitAsync(ct)) return existingDevice;\n        }\n        catch (Exception ex)\n        {\n            logger.LogError(ex, \"There was an error when updating your device\");\n            await unitOfWork.RollbackAsync(ct);\n        }\n\n        return null;\n    }\n\n    public async Task<bool> Delete(AppUser userWithDevices, int deviceId, CancellationToken ct = default)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/DeviceService.cs#L44-L80","documentation":"Thrown by DeviceService.Update when the device with dto.Id is not found in the user's Devices collection. Despite the message 'device-not-created', this is actually a 'not found' error during an update operation — the name is misleading. The lookup uses SingleOrDefault(d => d.Id == dto.Id) on the in-memory collection.","triggerScenarios":"User edits a device that was already deleted; the device ID in the update DTO does not match any device the user owns; userWithDevices.Devices was not eagerly loaded (would make SingleOrDefault always return null).","commonSituations":"Stale device list in the UI after a device was removed; the user's Devices navigation collection wasn't loaded by the calling code; concurrent sessions where one deletes a device while another tries to update it.","solutions":["Refresh the device list before editing to get current device IDs","Ensure the calling controller loads the user with Devices included before calling Update","Handle the KavitaException and return a clear 'device not found' error to the client"],"exampleFix":"// Ensure devices are eagerly loaded:\n// var user = await unitOfWork.UserRepository.GetUserByIdAsync(userId)\n//     ?? throw new KavitaException(\"user-not-found\");\n// // Confirm user.Devices is populated via Include in the repository query\n// await deviceService.Update(dto, user, ct);","handlingStrategy":"validation","validationCode":"// Ensure the device exists before updating:\n// var existing = userWithDevices.Devices?.SingleOrDefault(d => d.Id == dto.Id);\n// if (existing == null) return NotFound(\"Device not found\");","typeGuard":"// Confirm user has Devices loaded before calling Update:\n// static bool IsDeviceInCollection(AppUser user, int deviceId) =>\n//     user.Devices?.Any(d => d.Id == deviceId) ?? false;","tryCatchPattern":"// try {\n//     var device = await deviceService.Update(dto, userWithDevices, ct);\n//     return Ok(device);\n// } catch (KavitaException ex) when (ex.Message == \"device-not-created\") {\n//     return NotFound(new { error = \"Device not found. It may have been removed.\" });\n// }","preventionTips":["Always load the user with Devices navigation property included before calling Update","Refresh the device list in the UI before editing","Note the misleading exception name — 'device-not-created' is actually a not-found error during update"],"tags":["device","not-found","update","eager-loading"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}