alibaba/COLA · error · JobException
Unexpected value '${value}'
Error message
Unexpected value '${value}' What it means
ExecutionStatus.fromValue(String) iterates all enum constants and throws JobException 'Unexpected value' when no constant name equals the input. It is a strict string-to-enum converter for persisted execution status values.
Source
Thrown at cola-components/cola-component-job/src/main/java/com/alibaba/cola/job/model/ExecutionStatus.java:29
COMPLETED,
FAILED,
RUNNING,
ROLLBACK_STARTED,
ROLLBACK_COMPLETED,
ROLLBACK_FAILED,
UNKNOWN;
public final static List<ExecutionStatus> ROLLBACK_STATUS = List.of(ROLLBACK_STARTED, ROLLBACK_FAILED,
ROLLBACK_COMPLETED);
@JsonCreator
public static ExecutionStatus fromValue(String value) {
for (ExecutionStatus s : ExecutionStatus.values()) {
if (s.name().equals(value)) {
return s;
}
}
throw new JobException("Unexpected value '" + value + "'");
}
public static boolean isRollback(ExecutionStatus executionStatus) {
return executionStatus != null && ROLLBACK_STATUS.contains(executionStatus);
}
public static boolean isTerminated(ExecutionStatus executionStatus) {
return executionStatus == ExecutionStatus.COMPLETED
|| executionStatus == ExecutionStatus.FAILED
|| isRollback(executionStatus);
}
}
View on GitHub (pinned to 352e1a8675)
Solutions
- Pass the exact enum constant name, e.g. ExecutionStatus.RUNNING.name()
- Trim and uppercase the incoming string before conversion
- Migrate legacy persisted values to current enum names, or add legacy constants
Example fix
// before ExecutionStatus s = ExecutionStatus.fromValue(status.trim().toLowerCase()); // after ExecutionStatus s = ExecutionStatus.fromValue(status.trim().toUpperCase());
Defensive patterns
Strategy: validation
Validate before calling
String v = raw == null ? null : raw.trim();
boolean known = Arrays.stream(ExecutionStatus.values()).anyMatch(s -> s.name().equals(v));
if (!known) throw new IllegalStateException("Unknown ExecutionStatus: " + raw); Type guard
java.util.Optional<ExecutionStatus> tryFromValue(String value) {
if (value == null) return Optional.empty();
return Arrays.stream(ExecutionStatus.values())
.filter(s -> s.name().equals(value.trim()))
.findFirst();
} Try / catch
try {
status = ExecutionStatus.fromValue(raw);
} catch (JobException e) {
if (e.getMessage().startsWith("Unexpected value")) {
log.error("Persisted status '{}' is not a valid ExecutionStatus", raw, e);
status = ExecutionStatus.FAILED; // or rethrow per policy
} else throw e;
} Prevention
- Store status.name() so round-trips are lossless
- Trim/normalize strings coming from DB or messages
- Keep enum names backward-compatible when refactoring persisted states
When it happens
Trigger: Calling ExecutionStatus.fromValue with a string that is not the exact name() of an enum constant (case-sensitive, no trimming).
Common situations: Loading status values persisted by an older version whose enum names changed; passing lowercase 'running' instead of 'RUNNING'; whitespace from DB columns or message payloads.
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
- not support repositoryType: ${jobProperties.getRepositoryTyp
- EXTENSION_NOT_FOUND
- BizScenario can not be null for extension
- EXTENSION_DEFINE_DUPLICATE
- EXTENSION_ILLEGAL
AI-assisted analysis of alibaba/COLA@352e1a8675 (2026-09-08).
Data as JSON: /api/errors/46a1abc75e48db0f.
Report an issue: GitHub.