Kareadita/Kavita · warning · KavitaException

{comparison} is not applicable for {fieldName}

Error message

{comparison} is not applicable for {fieldName}

What it means

Thrown by ComparisonProfile.Validate when a FilterComparison enum value is not in the allowed set for a given field type (String/Numeric/List/Date sets defined in ComparisonProfile.cs). Example: GreaterThan on a string field, or IsBefore on a numeric field. Message is interpolated as '{comparison} is not applicable for {fieldName}'.

Source

Thrown at Kavita.Database/Extensions/Filters/ComparisonProfile.cs:84

    [
        FilterComparison.Equal, FilterComparison.NotEqual,
        FilterComparison.GreaterThan, FilterComparison.GreaterThanEqual,
        FilterComparison.LessThan, FilterComparison.LessThanEqual,
        FilterComparison.IsBefore, FilterComparison.IsAfter,
        FilterComparison.IsInLast, FilterComparison.IsNotInLast,
        FilterComparison.IsEmpty, FilterComparison.IsNotEmpty
    ];

    /// <summary>
    /// Throws <see cref="KavitaException"/> if the comparison is not in the allowed set.
    /// </summary>
    /// <param name="comparison">The comparison to validate</param>
    /// <param name="allowed">The set of allowed comparisons for this field</param>
    /// <param name="fieldName">The field name for the error message (e.g. "Person.Name")</param>
    public static void Validate(FilterComparison comparison, HashSet<FilterComparison> allowed, string fieldName)
    {
        if (!allowed.Contains(comparison))
            throw new KavitaException($"{comparison} is not applicable for {fieldName}");
    }
}

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Send only the comparison operators the field type allows per ComparisonProfile (String/Numeric/List/Date sets).
  2. On the client, constrain the operator dropdown to the field type's valid set before submitting.
  3. If you added a new field type, ensure its allowed FilterComparison set in ComparisonProfile is correct.

Example fix

// before - GreaterThan on a string field
ComparisonProfile.Validate(FilterComparison.GreaterThan, ComparisonProfile.String, "Person.Name");

// after - use an operator valid for string fields
ComparisonProfile.Validate(FilterComparison.Matches, ComparisonProfile.String, "Person.Name");
Defensive patterns

Strategy: validation

Validate before calling

if (!allowedSet.Contains(requestedComparison))
    return BadRequest($"{requestedComparison} is not valid for {field}");

Type guard

static bool IsValidComparison(FilterComparison c, HashSet<FilterComparison> allowed)
    => allowed.Contains(c);

Try / catch

try { ComparisonProfile.Validate(comp, ComparisonProfile.String, "Name"); }
catch (KavitaException ex) { return BadRequest(ex.Message); }

Prevention

When it happens

Trigger: A smart-filter / API filter request sends a predicate whose comparison operator is invalid for that field's type — e.g. matching Person.Name with FilterComparison.GreaterThan, or a date-only operator (IsInLast) on a numeric field. Validation runs at the top of each filter-building method.

Common situations: Frontend dropdown sends a stale operator after the field type changed; hand-built filter JSON with a wrong comparison; a newly added field whose allowed-set wasn't updated in ComparisonProfile.

Related errors


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