Kareadita/Kavita · error · KavitaException
profile-does-not-exist
Error message
profile-does-not-exist
What it means
Thrown by UpdateParent when GetUserProfile(userId, dto.Id) returns null — the target reading profile that should be merged into the series' parent profile does not exist for the user. The literal 'profile-does-not-exist' is a localization key surfaced to the UI. UpdateParent deletes the named profile and applies its settings onto the resolved parent profile.
Source
Thrown at Kavita.Services/Reading/ReadingProfileService.cs:41
public async Task<AppUserReadingProfile> GetReadingProfileForSeries(int userId, int libraryId, int seriesId,
int? activeDeviceId, bool skipImplicit = false)
{
return await unitOfWork.AppUserReadingProfileRepository.GetProfileForSeries(userId, libraryId, seriesId,
activeDeviceId, skipImplicit);
}
public async Task<UserReadingProfileDto> GetReadingProfileDtoForSeries(int userId, int libraryId, int seriesId,
int? activeDeviceId, bool skipImplicit = false)
{
return mapper.Map<UserReadingProfileDto>(await GetReadingProfileForSeries(userId, libraryId, seriesId,
activeDeviceId, skipImplicit));
}
public async Task<UserReadingProfileDto> UpdateParent(int userId, int libraryId, int seriesId,
UserReadingProfileDto dto, int? activeDeviceId)
{
var profile = await unitOfWork.AppUserReadingProfileRepository.GetUserProfile(userId, dto.Id);
if (profile == null) throw new KavitaException("profile-does-not-exist");
var parentProfile = await GetReadingProfileForSeries(userId, libraryId, seriesId, activeDeviceId, true);
UpdateReaderProfileFields(parentProfile, dto, false);
unitOfWork.AppUserReadingProfileRepository.Update(parentProfile);
// Delete profile as we'll be using the parent now
unitOfWork.AppUserReadingProfileRepository.Remove(profile);
await unitOfWork.CommitAsync();
return mapper.Map<UserReadingProfileDto>(parentProfile);
}
public async Task<UserReadingProfileDto> UpdateReadingProfile(int userId, UserReadingProfileDto dto)
{
var profile = await unitOfWork.AppUserReadingProfileRepository.GetUserProfile(userId, dto.Id);
if (profile == null) throw new KavitaException("profile-does-not-exist");
View on GitHub (pinned to 9c3e540000)
Solutions
- Refresh the user's reading profile list and retry with a current profile id.
- Verify the profile id belongs to the requesting user and still exists.
- Handle the not-found case gracefully in the UI instead of retrying the same stale id.
Defensive patterns
Strategy: validation
Validate before calling
var exists = await unitOfWork.AppUserReadingProfileRepository.GetUserProfile(userId, dto.Id) is not null;
if (!exists) return NotFound("profile-does-not-exist");
await profileService.UpdateParent(userId, libraryId, seriesId, dto, activeDeviceId); Type guard
public static bool ProfileFound(AppUserReadingProfile? p) => p is not null;
Try / catch
try { await profileService.UpdateParent(userId, libraryId, seriesId, dto, activeDeviceId); }
catch (KavitaException ex) when (ex.Message == "profile-does-not-exist") { return NotFound(); } Prevention
- Refresh the profile list in the UI before merge/update actions.
- Pass only currently-valid profile ids; discard stale references after deletes.
When it happens
Trigger: Client sends a profile id (dto.Id) that was already deleted, belongs to another user, or never existed; concurrent profile edits deleted it between load and update.
Common situations: UI had a stale profile id after another tab deleted it; profile was reset/cleared; id mismatch after a data migration.
Related errors
- library-doesnt-exist
- name-already-in-use
- cant-delete-default-profile
- cant-assign-devices-to-default
- reading-profiles-device-overlap
AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13).
Data as JSON: /api/errors/020794b4daf42fb3.
Report an issue: GitHub.