Kareadita/Kavita · error · KavitaException
device-not-created
Error message
device-not-created
What it means
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.
Source
Thrown at Kavita.Services/DeviceService.cs:62
if (!unitOfWork.HasChanges()) return existingDevice;
if (await unitOfWork.CommitAsync(ct)) return existingDevice;
}
catch (Exception ex)
{
logger.LogError(ex, "There was an error when creating your device");
await unitOfWork.RollbackAsync(ct);
}
return null;
}
public async Task<Device?> Update(UpdateEmailDeviceDto dto, AppUser userWithDevices, CancellationToken ct = default)
{
try
{
var existingDevice = userWithDevices.Devices.SingleOrDefault(d => d.Id == dto.Id);
if (existingDevice == null) throw new KavitaException("device-not-created");
existingDevice.Name = dto.Name;
existingDevice.Platform = dto.Platform;
existingDevice.EmailAddress = dto.EmailAddress;
if (!unitOfWork.HasChanges()) return existingDevice;
if (await unitOfWork.CommitAsync(ct)) return existingDevice;
}
catch (Exception ex)
{
logger.LogError(ex, "There was an error when updating your device");
await unitOfWork.RollbackAsync(ct);
}
return null;
}
public async Task<bool> Delete(AppUser userWithDevices, int deviceId, CancellationToken ct = default)View on GitHub (pinned to 9c3e540000)
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
Example fix
// Ensure devices are eagerly loaded:
// var user = await unitOfWork.UserRepository.GetUserByIdAsync(userId)
// ?? throw new KavitaException("user-not-found");
// // Confirm user.Devices is populated via Include in the repository query
// await deviceService.Update(dto, user, ct); Defensive patterns
Strategy: validation
Validate before calling
// Ensure the device exists before updating:
// var existing = userWithDevices.Devices?.SingleOrDefault(d => d.Id == dto.Id);
// if (existing == null) return NotFound("Device not found"); Type guard
// Confirm user has Devices loaded before calling Update: // static bool IsDeviceInCollection(AppUser user, int deviceId) => // user.Devices?.Any(d => d.Id == deviceId) ?? false;
Try / catch
// try {
// var device = await deviceService.Update(dto, userWithDevices, ct);
// return Ok(device);
// } catch (KavitaException ex) when (ex.Message == "device-not-created") {
// return NotFound(new { error = "Device not found. It may have been removed." });
// } Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- collection-doesnt-exist
- device-doesnt-exist
- library-doesnt-exist
- Bookmarks cannot be null!
- client-device-doesnt-exist
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/3ec6dee1e245abe7.
Report an issue: GitHub.