apache/seatunnel · error · IllegalArgumentException
Sparse vector value must be a Number, but got: %s
Error message
Sparse vector value must be a Number, but got: %s
What it means
convertSparseVectorToFloatArray requires every value in the sparse vector map to be a java.lang.Number so it can call floatValue(). This IllegalArgumentException is thrown when a value is some other type, naming the offending value's class.
Source
Thrown at seatunnel-common/src/main/java/org/apache/seatunnel/common/utils/VectorUtils.java:164
int index = (Integer) key;
if (index < 0) {
throw new IllegalArgumentException(
String.format("Sparse vector index cannot be negative: %d", index));
}
// prevent OOM
if (index > 1000000) {
throw new IllegalArgumentException(
String.format("Sparse vector index too large: %d", index));
}
maxIndex = Math.max(maxIndex, index);
}
Float[] denseVector = new Float[maxIndex + 1];
Arrays.fill(denseVector, 0.0f);
for (Map.Entry<?, ?> entry : sparseVector.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
if (!(value instanceof Number)) {
throw new IllegalArgumentException(
String.format(
"Sparse vector value must be a Number, but got: %s",
value.getClass().getName()));
}
int index = (Integer) key;
denseVector[index] = ((Number) value).floatValue();
}
return denseVector;
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Inspect the logged class name and convert values to a numeric type before the call (e.g. Float.parseFloat(str)).
- Fix the deserialization layer so numbers stay numeric (use a JSON mapper that infers number types).
- Ensure the map is typed Map<Integer, ? extends Number> at the call site.
- Pre-validate all values with instanceof Number and reject/convert non-numeric entries.
Example fix
// before
Map<String, String> raw = Map.of("0", "0.5");
Float[] dense = VectorUtils.convertSparseVectorToFloatArray(raw); // throws
// after
Map<Integer, Float> v = raw.entrySet().stream()
.collect(Collectors.toMap(e -> Integer.parseInt(e.getKey()), e -> Float.parseFloat(e.getValue())));
Float[] dense2 = VectorUtils.convertSparseVectorToFloatArray(v); Defensive patterns
Strategy: type-guard
Validate before calling
boolean allNumeric(Map<?,?> v) { return v.values().stream().allMatch(x -> x instanceof Number); } Type guard
boolean isNumber(Object o) { return o instanceof Number; } Try / catch
try { Float[] d = VectorUtils.convertSparseVectorToFloatArray(v); } catch (IllegalArgumentException e) { /* convert value types per the message and retry */ } Prevention
- Type maps as Map<Integer, ? extends Number>
- Ensure JSON deserialization preserves numeric types
- Convert string numbers explicitly before the call
When it happens
Trigger: Passing a Map<?, ?> whose values are Strings, boxed-but-stringified decimals, or arbitrary objects instead of numeric types; typically when the sparse vector comes from deserialized JSON/config where numbers became strings.
Common situations: Parsing sparse vectors from JSON where floats were serialized as strings ('0.5'), building vectors from raw config maps (Typesafe Config returns heterogeneous types), or schema drift in an upstream producer.
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
- Sparse vector key must be Integer, but got: %s,
- Sparse vector index too large: %d
- Unsupported timestamp type:
- Value is not a BSON date or timestamp
- Unable to convert to LocalDate from unexpected value '' of t
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/fc2075e3e5fcd9e4.
Report an issue: GitHub.