spring-projects/spring-ai · warning · UnsupportedOperationException
This is a utility class and cannot be instantiated
Error message
This is a utility class and cannot be instantiated
What it means
UsageCalculator is a final utility class whose private constructor deliberately throws UnsupportedOperationException("This is a utility class and cannot be instantiated"). It only offers static methods (e.g. accumulateUsage), so instantiation is a programming mistake. The library throws this to enforce the utility-class pattern.
Source
Thrown at spring-ai-model/src/main/java/org/springframework/ai/support/UsageCalculator.java:35
package org.springframework.ai.support;
import org.jspecify.annotations.Nullable;
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
import org.springframework.ai.chat.metadata.DefaultUsage;
import org.springframework.ai.chat.metadata.Usage;
import org.springframework.ai.chat.model.ChatResponse;
/**
* A utility class to provide support methods handling {@link Usage}.
*
* @author Ilayaperumal Gopinathan
* @author Jewoo Shin
*/
public final class UsageCalculator {
private UsageCalculator() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
/**
* Accumulate usage tokens from the previous chat response to the current usage
* tokens.
* <p>
* Note: when the two usages are actually summed, the result is a plain
* {@link DefaultUsage} and the provider-specific {@link Usage#getNativeUsage() native
* usage} object is <em>not</em> preserved (it cannot be merged across responses).
* Only the token counts and cache metrics carry over. The original
* {@code currentUsage} (native usage included) is returned unchanged when there is
* nothing to accumulate.
* @param currentUsage the current usage.
* @param previousChatResponse the previous chat response.
* @return accumulated usage.
*/
public static Usage getCumulativeUsage(final Usage currentUsage,
final @Nullable ChatResponse previousChatResponse) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Use the static methods directly, e.g. UsageCalculator.getUsage(previousResponse, currentResponse)
- Remove any @Bean/@Component registration or 'new UsageCalculator()' usage
- If wiring is needed, wrap it in your own service class instead of instantiating it
Example fix
// before UsageCalculator calc = new UsageCalculator(); Usage usage = calc.getUsage(prev, curr); // after Usage usage = UsageCalculator.getUsage(prev, curr);
Defensive patterns
Strategy: type-guard
Validate before calling
// Never instantiate; detect accidental reflective instantiation early
if (UsageCalculator.class.getDeclaredConstructors().length > 0) { /* utility class, use statics */ } Type guard
boolean isUtilityClassMisuse = false;
try { UsageCalculator.class.getDeclaredConstructor().newInstance(); isUtilityClassMisuse = true; }
catch (ReflectiveOperationException ignored) { }
// isUtilityClassMisuse == true means someone tried to instantiate it Try / catch
try {
Usage usage = UsageCalculator.getUsage(prev, curr);
} catch (UnsupportedOperationException e) {
// you instantiated the utility class somewhere; fix the call site
throw new AssertionError("Use UsageCalculator static methods", e);
} Prevention
- Call static methods on the class directly
- Never register utility classes as Spring beans
- Watch for IDE auto-completion offering a constructor
When it happens
Trigger: Calling new UsageCalculator() directly, or invoking reflection/bean-wiring that attempts to instantiate the class instead of using its static methods.
Common situations: Registering UsageCalculator as a Spring bean by mistake, copying code that instantiates other helper classes, or IDE auto-import followed by 'new UsageCalculator()'.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- No @Tool annotated methods found in %s. Did you mean to pass
- Failed to instantiate ToolCallResultConverter:
- This is a utility class and cannot be instantiated
- This is a utility class and cannot be instantiated
- instantiation failed
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/ab46a7a7d2fd31c4.
Report an issue: GitHub.