alibaba/COLA · error · ClassCastException
Value for key=[${key}] is not of type: [${type}], it is [(${
Error message
Value for key=[${key}] is not of type: [${type}], it is [(${value.getClass()})${value}] What it means
ExecutionContext.get(key, type, defaultValue) throws ClassCastException when the stored value for the key exists but is not an instance of the requested type V. It is an eager, message-rich substitute for a lazy ClassCastException from type.cast.
Source
Thrown at cola-components/cola-component-job/src/main/java/com/alibaba/cola/job/ExecutionContext.java:145
@Nullable
public Object get(String key) {
return this.extensions.get(key);
}
@Nullable
public <V> V get(String key, Class<V> type) {
Object value = this.extensions.get(key);
return value == null ? null : this.get(key, type, null);
}
@Nullable
public <V> V get(String key, Class<V> type, @Nullable V defaultValue) {
Object value = this.extensions.get(key);
if (value == null) {
return defaultValue;
} else if (!type.isInstance(value)) {
throw new ClassCastException(
"Value for key=[" + key + "] is not of type: [" + type + "], it is [(" + value.getClass() + ")" + value
+ "]");
} else {
return type.cast(value);
}
}
public boolean containsKey(String key) {
return this.extensions.containsKey(key);
}
@Nullable
public Object remove(String key) {
return this.extensions.remove(key);
}
public boolean containsValue(Object value) {
return this.extensions.containsValue(value);View on GitHub (pinned to 352e1a8675)
Solutions
- Align the Class<V> argument with the type actually put into the context
- Fix the writer side to store the expected type under that key
- Use a distinct key per type to avoid collisions between steps
Example fix
// before
String name = ctx.get("count", String.class, "0"); // count stored as Integer
// after
Integer count = ctx.get("count", Integer.class, 0); Defensive patterns
Strategy: type-guard
Validate before calling
Object raw = executionContext.get(key);
if (raw != null && !type.isInstance(raw)) {
throw new IllegalStateException("key '" + key + "' holds " + raw.getClass() + ", expected " + type);
} Type guard
<V> V safeGet(ExecutionContext ctx, String key, Class<V> type, V def) {
Object v = ctx.get(key);
return type.isInstance(v) ? type.cast(v) : def;
} Try / catch
try {
value = executionContext.get(key, Foo.class, defaultFoo);
} catch (ClassCastException e) {
log.warn("Type mismatch for key {} in execution context; using default", key, e);
value = defaultFoo;
} Prevention
- Use one key per type; encode type in the key name (e.g. 'retryCount:Integer')
- Centralize context read/write in typed accessor methods
- Watch for duplicate classes from different classloaders in app servers
When it happens
Trigger: Calling executionContext.get("someKey", Foo.class, def) while a value of an incompatible class (e.g. Integer vs String, or two different versions of the same class) was stored under that key via put/extension map.
Common situations: Writing a String and reading as Integer; job step A stores one type and step B reads another; classloader duplicates (same class name, different Class objects) in app-server deployments.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- EXTENSION_NOT_FOUND
- BizScenario can not be null for extension
- EXTENSION_DEFINE_DUPLICATE
- EXTENSION_ILLEGAL
- EXTENSION_INTERFACE_NAME_ILLEGAL
AI-assisted analysis of alibaba/COLA@352e1a8675 (2026-09-08).
Data as JSON: /api/errors/7e19c022db143c8a.
Report an issue: GitHub.