fullstackhero/dotnet-starter-kit · error · CustomException

Unknown category ' '.

Error message

Unknown category '{cmd.Category}'.

What it means

CustomException with HttpStatusCode.BadRequest thrown when cmd.Category is not a key in FilesOptions.Categories. The set of legal categories (e.g. avatar, attachment) is configured via options binding, and the handler refuses any category string it cannot resolve to a configured category definition.

Solutions

  1. Use a category that exists in the configured Files:Categories section (check appsettings/environment for exact keys).
  2. Add the missing category to configuration under the Files options (name, allowed extensions, max bytes) if it is a legitimate new category.
  3. Trim/normalize the category string on the client and match the configured casing exactly.
  4. Add a FluentValidation rule on RequestUploadUrlCommandValidator to reject unknown categories with a clear message before the handler runs.

Example fix

// before
await requestUploadUrl({ category: "avatars", ... }); // not configured
// after
await requestUploadUrl({ category: "avatar", ... }); // matches Files:Categories:avatar in appsettings
Defensive patterns

Strategy: validation

Validate before calling

const allowed = ["avatar", "attachment"]; // mirror of Files:Categories keys
if (!allowed.includes(category)) throw new Error(`Unknown category '${category}'`);

Try / catch

try { await requestUploadUrl(cmd); } catch (e) { if (e.status === 400 && e.message?.startsWith("Unknown category")) { showToast("Selected file category is not available"); } else throw e; }

Prevention

When it happens

Trigger: Posting RequestUploadUrlCommand with a category value that is not registered in configuration (e.g. typo 'avatars' vs 'avatar', wrong casing if the options dictionary is case-sensitive, or a category removed from appsettings/env config).

Common situations: Client hardcoded a category that the deployment's Files:Categories config does not define; config section renamed or not bound (missing Files options registration); environments (staging/prod) configured with fewer categories than the frontend offers; category string passed with different casing or trailing whitespace.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Modules/Files/Modules.Files/Features/v1/RequestUploadUrl/RequestUploadUrlCommandHandler.cs:41

    ICurrentUser currentUser,
    IOptions<FilesOptions> options)
    : ICommandHandler<RequestUploadUrlCommand, PresignedUploadResponse>
{
    public async ValueTask<PresignedUploadResponse> Handle(RequestUploadUrlCommand cmd, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(cmd);

        var tenantId = currentUser.GetTenant() ?? throw new UnauthorizedException("invalid tenant");
        var userId = currentUser.GetUserId();
        if (userId == Guid.Empty)
        {
            throw new UnauthorizedException("no current user");
        }

        // Category lookup + extension/size validation.
        if (!options.Value.Categories.TryGetValue(cmd.Category, out var category))
        {
            throw new CustomException($"Unknown category '{cmd.Category}'.", (IEnumerable<string>?)null, HttpStatusCode.BadRequest);
        }

        var extension = Path.GetExtension(cmd.FileName);
        if (string.IsNullOrWhiteSpace(extension) ||
            !category.AllowedExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
        {
            throw new CustomException(
                $"Extension '{extension}' not allowed for category '{cmd.Category}'.",
                (IEnumerable<string>?)null,
                HttpStatusCode.BadRequest);
        }

        if (cmd.SizeBytes > category.MaxBytes)
        {
            throw new CustomException(
                $"File exceeds max size of {category.MaxBytes} bytes for category '{cmd.Category}'.",
                (IEnumerable<string>?)null,
                HttpStatusCode.BadRequest);

View on GitHub (pinned to 3f2959e683)