microsoft/semantic-kernel · error · TextModerationException

Offensive content detected. Operation is denied.

Error message

Offensive content detected. Operation is denied.

What it means

TextModerationFilter calls Azure Content Safety text moderation and throws TextModerationException when any category's Severity is greater than 0. Severity is set high whenever at least one analysis category is non-zero. The exception carries CategoriesAnalysis so callers can see which category (hate, sexual, violence, self-harm) and what severity triggered the block.

Source

Thrown at dotnet/samples/Demos/ContentSafety/Filters/TextModerationFilter.cs:64

    {
        var highSeverity = false;
        var analysisDetails = new Dictionary<TextCategory, int>();

        foreach (var analysis in analysisResult.CategoriesAnalysis)
        {
            this._logger.LogInformation("Category: {Category}. Severity: {Severity}", analysis.Category, analysis.Severity);

            if (analysis.Severity > 0)
            {
                highSeverity = true;
            }

            analysisDetails.Add(analysis.Category, analysis.Severity ?? 0);
        }

        if (highSeverity)
        {
            throw new TextModerationException("Offensive content detected. Operation is denied.")
            {
                CategoriesAnalysis = analysisDetails
            };
        }
    }
}

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Inspect ex.CategoriesAnalysis to identify the offending category and its severity level.
  2. Reject or rewrite the flagged input, then retry.
  3. If false positives, raise the accepted-severity gate (block only when Severity >= 4, for example) instead of `> 0`.
  4. Return a controlled error to the client rather than letting the exception propagate.

Example fix

// before
if (analysis.Severity > 0) highSeverity = true;
...
if (highSeverity) throw new TextModerationException(...) ;

// after (configurable threshold)
const int BlockAbove = 2; // 0-6 scale, tune per policy
if ((analysis.Severity ?? 0) >= BlockAbove) highSeverity = true;
Defensive patterns

Strategy: validation

Validate before calling

const int BlockAbove = 2;
bool highSeverity = analysis.Any(a => (a.Severity ?? 0) >= BlockAbove);
// then only block when highSeverity is true

Type guard

static bool ExceedsThreshold(IEnumerable<Analysis> items, int threshold) =>
    items.Any(a => (a.Severity ?? 0) >= threshold);

Try / catch

try { await kernel.InvokeAsync(...); }
catch (TextModerationException ex)
{
    logger.LogWarning("Moderation block: {Cats}",
        string.Join(",", ex.CategoriesAnalysis));
    return Results.BadRequest("Input rejected by content moderation.");
}

Prevention

When it happens

Trigger: At least one CategoriesAnalysis entry has Severity > 0 (the `if (analysis.Severity > 0)` sets highSeverity=true), so the final `if (highSeverity)` branch throws.

Common situations: User-generated or ingested text contains profanity/objectionable content; a content source is noisier than expected; severity thresholds need tuning for the use case.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/e5e03a01be1ddf40. Report an issue: GitHub.