fullstackhero/dotnet-starter-kit · error · CustomException

Another product with name

Error message

Another product with name '{command.Name}' already exists.

What it means

After updating, the handler slugifies the product name and checks whether another product already uses that slug; if so it throws CustomException with HTTP 409 Conflict — product names (via slugs) must be unique per module rules.

Solutions

  1. Pick a different product name (add a variant/suffix) and retry.
  2. Check the existing product list for the colliding name before saving.
  3. If the two products should be one, delete/merge the duplicate instead of renaming.
  4. Catch CustomException with the 409 status in the client and show a friendly 'name taken' message.

Example fix

// before
await mediator.Send(new UpdateProductCommand { ProductId = id, Name = newName });
// after
var slug = newName.ToSlug();
bool taken = await db.Products.AnyAsync(p => p.Slug == slug && p.Id != id, ct);
if (taken) newName = $"{newName} 2"; // or prompt user
await mediator.Send(new UpdateProductCommand { ProductId = id, Name = newName }, ct);
Defensive patterns

Strategy: try-catch

Validate before calling

var slug = newName.ToSlug();
bool taken = await dbContext.Products.AnyAsync(p => p.Slug == slug && p.Id != productId, ct);
if (taken) throw new ValidationException("Another product already uses this name.");

Try / catch

try { await mediator.Send(cmd, ct); }
catch (CustomException ex) when (ex.StatusCode == HttpStatusCode.Conflict)
{ ModelState.AddModelError(nameof(cmd.Name), "Product name already in use"); return Results.Conflict(); }

Prevention

When it happens

Trigger: UpdateProductCommand renaming a product to a name whose generated slug matches another product's slug (p.Slug == product.Slug && p.Id != product.Id). Also fires when only casing/punctuation changes, since slugify normalizes them to the same slug.

Common situations: Two editors rename different products to the same title; renaming 'Pro X' when 'Pro X' already exists (identical slugs); bulk import scripts not checking name collisions.

Related errors


AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15). Data as JSON: /api/errors/4c7da8ca76e5b3e6. Report an issue: GitHub.

Appendix: source

Thrown at src/Modules/Catalog/Modules.Catalog/Features/v1/Products/UpdateProduct/UpdateProductCommandHandler.cs:56

            if (!categoryExists)
            {
                throw new NotFoundException($"Category {command.CategoryId} not found.");
            }
        }

        product.Update(
            command.Name,
            command.Description,
            command.BrandId,
            command.CategoryId,
            command.IsActive);

        bool slugTaken = await dbContext.Products
            .AnyAsync(p => p.Slug == product.Slug && p.Id != product.Id, cancellationToken)
            .ConfigureAwait(false);
        if (slugTaken)
        {
            throw new CustomException(
                $"Another product with name '{command.Name}' already exists.",
                (IEnumerable<string>?)null,
                HttpStatusCode.Conflict);
        }

        await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
        return product.Id;
    }
}

View on GitHub (pinned to 3f2959e683)