spring-projects/spring-ai · error · java.lang.IllegalArgumentException
Unknown HarmCategory:
Error message
Unknown HarmCategory:
What it means
mapToGenAiHarmCategory converts Spring AI GoogleGenAiSafetySetting.HarmCategory enums to genai SDK HarmCategory values; an unknown/unmapped category throws IllegalArgumentException. This indicates the safety category enum was extended without updating the mapper, or an unexpected value reached the switch.
Source
Thrown at models/spring-ai-google-genai/src/main/java/org/springframework/ai/google/genai/GoogleGenAiChatModel.java:830
prompt.getInstructions().stream().filter(m -> m.getMessageType() != MessageType.SYSTEM).toList()),
modelName, config);
}
// Helper methods for mapping safety settings enums
private static com.google.genai.types.HarmCategory mapToGenAiHarmCategory(
GoogleGenAiSafetySetting.HarmCategory category) {
return switch (category) {
case HARM_CATEGORY_UNSPECIFIED -> new com.google.genai.types.HarmCategory(
com.google.genai.types.HarmCategory.Known.HARM_CATEGORY_UNSPECIFIED);
case HARM_CATEGORY_HATE_SPEECH -> new com.google.genai.types.HarmCategory(
com.google.genai.types.HarmCategory.Known.HARM_CATEGORY_HATE_SPEECH);
case HARM_CATEGORY_DANGEROUS_CONTENT -> new com.google.genai.types.HarmCategory(
com.google.genai.types.HarmCategory.Known.HARM_CATEGORY_DANGEROUS_CONTENT);
case HARM_CATEGORY_HARASSMENT -> new com.google.genai.types.HarmCategory(
com.google.genai.types.HarmCategory.Known.HARM_CATEGORY_HARASSMENT);
case HARM_CATEGORY_SEXUALLY_EXPLICIT -> new com.google.genai.types.HarmCategory(
com.google.genai.types.HarmCategory.Known.HARM_CATEGORY_SEXUALLY_EXPLICIT);
default -> throw new IllegalArgumentException("Unknown HarmCategory: " + category);
};
}
private static com.google.genai.types.HarmBlockThreshold mapToGenAiHarmBlockThreshold(
GoogleGenAiSafetySetting.HarmBlockThreshold threshold) {
return switch (threshold) {
case HARM_BLOCK_THRESHOLD_UNSPECIFIED -> new com.google.genai.types.HarmBlockThreshold(
com.google.genai.types.HarmBlockThreshold.Known.HARM_BLOCK_THRESHOLD_UNSPECIFIED);
case BLOCK_LOW_AND_ABOVE -> new com.google.genai.types.HarmBlockThreshold(
com.google.genai.types.HarmBlockThreshold.Known.BLOCK_LOW_AND_ABOVE);
case BLOCK_MEDIUM_AND_ABOVE -> new com.google.genai.types.HarmBlockThreshold(
com.google.genai.types.HarmBlockThreshold.Known.BLOCK_MEDIUM_AND_ABOVE);
case BLOCK_ONLY_HIGH -> new com.google.genai.types.HarmBlockThreshold(
com.google.genai.types.HarmBlockThreshold.Known.BLOCK_ONLY_HIGH);
case BLOCK_NONE -> new com.google.genai.types.HarmBlockThreshold(
com.google.genai.types.HarmBlockThreshold.Known.BLOCK_NONE);
case OFF ->
new com.google.genai.types.HarmBlockThreshold(com.google.genai.types.HarmBlockThreshold.Known.OFF);View on GitHub (pinned to 98a7beda4f)
Solutions
- Use only the mapped categories: HARM_CATEGORY_DANGEROUS_CONTENT, HARM_CATEGORY_HARASSMENT, HARM_CATEGORY_SEXUALLY_EXPLICIT (and any others the current source maps).
- Print the offending category value from the exception message and align your safety settings configuration.
- Upgrade or patch the module if a newly added enum constant is missing from the mapper.
- Avoid building categories from arbitrary strings via valueOf.
Example fix
// before new GoogleGenAiSafetySetting(HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold); // if unmapped // after new GoogleGenAiSafetySetting(HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold);
Defensive patterns
Strategy: type-guard
Validate before calling
private static final Set<HarmCategory> SUPPORTED = Set.of(HARM_CATEGORY_DANGEROUS_CONTENT, HARM_CATEGORY_HARASSMENT, HARM_CATEGORY_SEXUALLY_EXPLICIT);
if (!SUPPORTED.contains(category)) throw new IllegalArgumentException("unsupported: " + category); Type guard
boolean isMapped(HarmCategory c) { return EnumSet.of(HARM_CATEGORY_DANGEROUS_CONTENT, HARM_CATEGORY_HARASSMENT, HARM_CATEGORY_SEXUALLY_EXPLICIT).contains(c); } Try / catch
try { applySafety(settings); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unknown HarmCategory")) fixConfig(); else throw e; } Prevention
- Only use enum constants documented as mapped
- Don't build enums from raw strings via valueOf
- Re-check safety settings after library upgrades
When it happens
Trigger: Passing a HarmCategory value to GoogleGenAiSafetySetting that the switch statement does not handle (e.g. HARM_CATEGORY_UNSPECIFIED, HARM_CATEGORY_HATE_SPEECH if unmapped, or a newly added enum constant).
Common situations: Upgrading spring-ai-google-genai where new enum constants appear; copying safety settings from another provider with different category names; typos when constructing categories dynamically from strings.
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
- Unknown HarmBlockThreshold:
- Incomplete Google GenAI configuration: Provide 'api-key' for
- Gemini doesn't support message type:
- Failed to generate content
- ThinkingLevel.%s is not supported for model '%s'. This model
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/6a16a0fbd5d89f7f.
Report an issue: GitHub.