alibaba/spring-ai-alibaba · error · IllegalStateException

Unexpected value:

Error message

Unexpected value: 

What it means

ScheduledAgentTask.start() switches over the ScheduleConfig mode (CRON, fixed rate/delay, TRIGGER); if the mode enum has an unexpected value not handled by any case (e.g. an unknown/added enum constant or corrupt config), the default branch throws IllegalStateException("Unexpected value: " + mode).

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/scheduling/ScheduledAgentTask.java:96

						new CronTrigger(config.getCronExpression()));
				break;
			case FIXED_DELAY:
				scheduledFuture = taskScheduler.scheduleWithFixedDelay(this::executeGraph,
						Instant.now().plusMillis(config.getInitialDelay()), Duration.ofMillis(config.getFixedDelay()));
				break;
			case FIXED_RATE:
				scheduledFuture = taskScheduler.scheduleAtFixedRate(this::executeGraph,
						Instant.now().plusMillis(config.getInitialDelay()), Duration.ofMillis(config.getFixedRate()));
				break;
			case ONE_TIME:
				scheduledFuture = taskScheduler.schedule(this::executeGraph,
						Instant.now().plusMillis(config.getInitialDelay()));
				break;
			case TRIGGER:
				scheduledFuture = taskScheduler.schedule(this::executeGraph, config.getTrigger());
				break;
			default:
				throw new IllegalStateException("Unexpected value: " + config.getMode());
		}

		started = true;
		notifyListeners(ScheduleLifecycleListener.ScheduleEvent.STARTED);
		return this;
	}

	/**
	 * Stop the scheduled execution
	 */
	public void stop() {
		if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
			scheduledFuture.cancel(false);
		}
		stopped = true;

		// Unregister from active manager
		ScheduledAgentManagerFactory.getInstance().getManager().unregisterTask(taskId);

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Upgrade spring-ai-alibaba-graph-core to a version whose start() handles your ScheduleMode value
  2. Use only the documented ScheduleMode values (CRON, fixed-rate, fixed-delay, TRIGGER)
  3. Check for classpath conflicts where two versions of the enum are loaded
  4. If you added an enum value, add a corresponding case to the switch

Example fix

// before
case TRIGGER:
    scheduledFuture = taskScheduler.schedule(this::executeGraph, config.getTrigger());
    break;
// after
case TRIGGER:
    scheduledFuture = taskScheduler.schedule(this::executeGraph, config.getTrigger());
    break;
case EVENT:
    scheduledFuture = taskScheduler.schedule(this::executeGraph, config.getEventTrigger());
    break;
Defensive patterns

Strategy: validation

Validate before calling

// verify mode is a value handled by start()
ScheduleMode mode = config.getMode();
if (mode != ScheduleMode.CRON && mode != ScheduleMode.FIXED_RATE
        && mode != ScheduleMode.FIXED_DELAY && mode != ScheduleMode.TRIGGER) {
    throw new IllegalArgumentException("unsupported schedule mode: " + mode);
}

Try / catch

try {
    task.start();
} catch (IllegalStateException e) {
    if (String.valueOf(e.getMessage()).startsWith("Unexpected value:")) {
        logger.error("ScheduleMode {} unsupported by this library version", config.getMode());
    } else throw e;
}

Prevention

When it happens

Trigger: ScheduleConfig.getMode() returns an enum constant not covered by the switch — typically after the ScheduleMode enum gained a new value while this switch wasn't updated, or a manually constructed/invalid mode value.

Common situations: Library version upgrade adding a new ScheduleMode; custom config loading producing an unexpected mode; reflection/manual enum construction in tests.

Related errors


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