Kareadita/Kavita · warning · KavitaException

name-already-in-use

Error message

name-already-in-use

What it means

Thrown by CreateReadingProfile when IsProfileNameInUse(userId, dto.Name) is true — the user already has a reading profile with that exact name. The 'name-already-in-use' localization key is surfaced to the UI. This is a business-rule validation guard, not a system fault.

Source

Thrown at Kavita.Services/Reading/ReadingProfileService.cs:72

    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");

        UpdateReaderProfileFields(profile, dto);
        unitOfWork.AppUserReadingProfileRepository.Update(profile);

        await unitOfWork.CommitAsync();
        return mapper.Map<UserReadingProfileDto>(profile);
    }

    public async Task<UserReadingProfileDto> CreateReadingProfile(int userId, UserReadingProfileDto dto)
    {
        var user = await unitOfWork.UserRepository.GetUserByIdAsync(userId, AppUserIncludes.UserPreferences);
        if (user == null) throw new UnauthorizedAccessException();

        if (await unitOfWork.AppUserReadingProfileRepository.IsProfileNameInUse(userId, dto.Name)) throw new KavitaException("name-already-in-use");

        var newProfile = new AppUserReadingProfileBuilder(user.Id).Build();
        UpdateReaderProfileFields(newProfile, dto);

        unitOfWork.AppUserReadingProfileRepository.Add(newProfile);
        user.ReadingProfiles.Add(newProfile);

        await unitOfWork.CommitAsync();

        return mapper.Map<UserReadingProfileDto>(newProfile);
    }

    public async Task<UserReadingProfileDto> PromoteImplicitProfile(int userId, int profileId, int? activeDeviceId)
    {
        // Get all the user's profiles including the implicit
        var allUserProfiles = await unitOfWork.AppUserReadingProfileRepository.GetProfilesForUser(userId);
        var profileToPromote = allUserProfiles.FirstOrDefault(rp => rp.Id == profileId);

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Choose a different, unique profile name for the user.
  2. Pre-check availability with IsProfileNameInUse before offering the create action in the UI.
  3. If merging was intended, update the existing profile instead of creating a new one.
Defensive patterns

Strategy: validation

Validate before calling

if (await unitOfWork.AppUserReadingProfileRepository.IsProfileNameInUse(userId, dto.Name))
    return Conflict("name-already-in-use");
await profileService.CreateReadingProfile(userId, dto);

Try / catch

try { await profileService.CreateReadingProfile(userId, dto); }
catch (KavitaException ex) when (ex.Message == "name-already-in-use") { return Conflict(ex.Message); }

Prevention

When it happens

Trigger: User submits a new profile with a name identical to an existing profile of theirs; profile names are enforced unique per user.

Common situations: User forgets a profile name is taken; duplicate submit from a double-click; UI didn't pre-check name availability.

Related errors


AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13). Data as JSON: /api/errors/49066f46cf43cf58. Report an issue: GitHub.