alibaba/spring-ai-alibaba · warning

Primary model failed: {}

Error message

Primary model failed: {}

What it means

ModelFallbackInterceptor.interceptModel catches any Exception thrown by the primary ChatModel call, logs 'Primary model failed' with the message, records it as lastException, and proceeds to iterate the configured fallbackModels in order. This is informational in the normal path; it only precedes a hard failure if every fallback also fails.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/modelfallback/ModelFallbackInterceptor.java:77

	@Override
	public ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {
		Exception lastException = null;

		// Try primary model first
		try {
			ModelResponse modelResponse = handler.call(request);
			Message message = (Message) modelResponse.getMessage();
			
			// Check if response contains error indicator
			if (message.getText() != null && message.getText().contains("Exception:")) {
				throw new RuntimeException(message.getText());
			}
			
			// Return successful response
			return modelResponse;
		}
		catch (Exception e) {
			log.warn("Primary model failed: {}", e.getMessage());
			lastException = e;
		}

		// Try fallback models in sequence
		for (int i = 0; i < fallbackModels.size(); i++) {
			ChatModel fallbackModel = fallbackModels.get(i);
			try {
				log.info("Trying fallback model {} of {}", i + 1, fallbackModels.size());

				// Call the fallback model directly
				Prompt prompt = new Prompt(request.getMessages(), request.getOptions());
				var response = fallbackModel.call(prompt);

				return ModelResponse.of(response.getResult().getOutput());
			}
			catch (Exception e) {
				log.warn("Fallback model {} failed: {}", i + 1, e.getMessage());
				lastException = e;

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Read the logged e.getMessage() to identify the underlying cause (auth vs network vs limit)
  2. Configure at least one healthy fallbackModel in the interceptor builder with compatible capabilities
  3. Fix the primary model's credentials/endpoint; a fallback chain should be a safety net, not the norm
  4. Add retry (ModelRetryInterceptor) in front of fallback for transient errors
  5. Monitor the warnings — frequent occurrences indicate the primary model config is broken

Example fix

// before
ModelFallbackInterceptor.of(primaryModel); // no fallbacks configured
// after
ModelFallbackInterceptor interceptor = ModelFallbackInterceptor.builder()
    .primaryModel(primaryModel)
    .fallbackModels(List.of(backupDashScopeModel, backupOpenAiModel))
    .build();
Defensive patterns

Strategy: fallback

Validate before calling

Objects.requireNonNull(primaryModel, "primary model required");
if (fallbackModels.isEmpty()) throw new IllegalStateException("ModelFallbackInterceptor needs at least one fallback model");

Type guard

boolean chainIsHealthy(List<ChatModel> models) { return models != null && !models.isEmpty() && models.stream().allMatch(Objects::nonNull); }

Try / catch

try { return interceptor.interceptModel(request, chain); }
catch (RuntimeException e) { log.error("All models failed", e); return degrade(request); }

Prevention

When it happens

Trigger: The primary model.call(prompt) throws — network/timeout errors, 401/403 auth failures, rate limits, model unavailability, or invalid options — during a ChatModel invocation routed through ModelFallbackInterceptor.

Common situations: Expired or missing DashScope/OpenAI API key; regional endpoint outage; request exceeding context limit; transient 429 rate limiting during bursts; misconfigured model name after a version upgrade.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/b1d0271c2bfd847b. Report an issue: GitHub.