alibaba/spring-ai-alibaba · warning · IllegalArgumentException

Status value cannot be null

Error message

Status value cannot be null

What it means

TodoListInterceptor.TodoStatus.fromValue() is the Jackson @JsonCreator for deserializing todo status strings. A null input cannot match any status, so it throws IllegalArgumentException before the value-matching loop runs.

Source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/todolist/TodoListInterceptor.java:140

	/**
	 * Todo item status.
	 */
	@JsonFormat(shape = JsonFormat.Shape.STRING)
	public enum TodoStatus {
		PENDING("pending"),
		IN_PROGRESS("in_progress"),
		COMPLETED("completed");

		private final String value;

		TodoStatus(String value) {
			this.value = value;
		}

		@JsonCreator
		public static TodoStatus fromValue(String value) {
			if (value == null) {
				throw new IllegalArgumentException("Status value cannot be null");
			}

			// First try to match against the lowercase values
			for (TodoStatus status : values()) {
				if (status.value.equals(value)) {
					return status;
				}
			}

			// Fallback: try to match against enum constant names (case-insensitive)
			try {
				return TodoStatus.valueOf(value.toUpperCase());
			}
			catch (IllegalArgumentException e) {
				// If that fails too, throw a helpful error
				throw new IllegalArgumentException(
						"Unknown status: " + value + ". Valid values are: pending, in_progress, completed");
			}

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Ensure todo items always carry a non-null status string before serialization/deserialization
  2. Default null to TodoStatus.PENDING in the owning code
  3. Wrap the parse in a null check and handle/replace malformed items

Example fix

// before
TodoStatus status = TodoStatus.fromValue(item.get("status")); // may be null
// after
String v = item.get("status");
TodoStatus status = v != null ? TodoStatus.fromValue(v) : TodoStatus.PENDING;
Defensive patterns

Strategy: type-guard

Validate before calling

String v = todo.get("status");
if (v == null || v.isBlank()) { v = "pending"; }
TodoStatus status = TodoStatus.fromValue(v);

Type guard

boolean hasStatus(JsonNode n) { return n.has("status") && !n.get("status").isNull(); }

Try / catch

try { status = TodoStatus.fromValue(value); } catch (IllegalArgumentException e) { status = TodoStatus.PENDING; }

Prevention

When it happens

Trigger: Deserializing a todo JSON whose "status" field is null or absent and fed explicitly as null into fromValue(); programmatic calls like TodoStatus.fromValue(null).

Common situations: LLM-produced todo JSON missing the status field; API payload with explicit null; calling the creator directly from tests or custom deserializers.

Related errors


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