alibaba/spring-ai-alibaba · warning · IllegalArgumentException
Unknown status: ${value}. Valid values are: pending, in_prog
Error message
Unknown status: ${value}. Valid values are: pending, in_progress, completed What it means
TodoStatus.fromValue() matches lowercase values (pending, in_progress, completed), then falls back to case-insensitive enum-name matching; if both fail it throws an IllegalArgumentException listing the valid values. This keeps the todo list schema strict so downstream state rendering is reliable.
Source
Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/interceptor/todolist/TodoListInterceptor.java:156
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");
}
}
@JsonValue
public String getValue() {
return value;
}
}
/**
* Represents a single todo item.
* <p>
* Task descriptions must have two forms:
* <ul>
* <li><b>content</b>: The imperative form describing what needs to be done (e.g., "Run tests", "Build the project")</li>
* <li><b>activeForm</b>: The present continuous form shown during execution (e.g., "Running tests", "Building the project").
* When null or blank, content is used as fallback for backward compatibility.</li>View on GitHub (pinned to f82da0b50f)
Solutions
- Send only pending, in_progress, or completed (case-insensitive enum names also accepted)
- Map/sanitize LLM output to a valid status before parsing
- Catch IllegalArgumentException and coerce to a default status
Example fix
// before "status": "done" // after "status": "completed"
Defensive patterns
Strategy: validation
Validate before calling
Set<String> VALID = Set.of("pending", "in_progress", "completed");
if (!VALID.contains(value.toLowerCase())) { value = mapAlias(value); }
TodoStatus status = TodoStatus.fromValue(value); Type guard
boolean isValidStatus(String s) { return s != null && (s.equals("pending") || s.equals("in_progress") || s.equals("completed") || s.equalsIgnoreCase("PENDING") || s.equalsIgnoreCase("IN_PROGRESS") || s.equalsIgnoreCase("COMPLETED")); } Try / catch
try { status = TodoStatus.fromValue(value); } catch (IllegalArgumentException e) { log.warn("Unknown status '{}', defaulting to PENDING", value); status = TodoStatus.PENDING; } Prevention
- List the exact allowed values in LLM prompts/tool schemas
- Normalize hyphens to underscores before parsing
- Map known aliases (done -> completed) before deserialization
When it happens
Trigger: Deserializing a status string such as "done", "finished", "in-progress" (hyphen instead of underscore), or any misspelled value that matches neither the value list nor the enum constant names.
Common situations: LLM emitting human-friendly statuses like "done" or "in-progress"; locale/uppercase mismatch handled by fallback but arbitrary words are not; older clients sending retired status names.
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
- Status value cannot be null
- Cannot instantiate class {} for @class deserialization
- Cannot instantiate class {} for @typeHint deserialization
- Cannot instantiate array type from scalar payload: {}
- Failed to deserialize store item
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/be2ee16163a369d1.
Report an issue: GitHub.