apache/seatunnel · error · IllegalArgumentException
Sparse vector index cannot be negative: %d
Error message
Sparse vector index cannot be negative: %d
What it means
While converting a sparse vector to a float array, each Integer key is treated as an array index; negative indexes are rejected with IllegalArgumentException 'Sparse vector index cannot be negative: <index>' before they can corrupt the output array. (Keys above 1,000,000 are likewise rejected to prevent OOM.)
Source
Thrown at seatunnel-common/src/main/java/org/apache/seatunnel/common/utils/VectorUtils.java:148
return intArray;
}
public static Float[] convertSparseVectorToFloatArray(Map<?, ?> sparseVector) {
if (sparseVector.isEmpty()) {
return new Float[0];
}
int maxIndex = -1;
for (Map.Entry<?, ?> entry : sparseVector.entrySet()) {
Object key = entry.getKey();
if (!(key instanceof Integer)) {
throw new IllegalArgumentException(
String.format(
"Sparse vector key must be Integer, but got: %s,",
key.getClass().getName()));
}
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",View on GitHub (pinned to cf67b549a7)
Solutions
- Correct the index computation upstream so keys are 0-based non-negative
- Filter or clamp negative keys before calling convertSparseVectorToFloatArray
- Validate input data at ingestion (reject negative indexes with a domain-appropriate message)
- Check for double-conversion from 1-based to 0-based indexing in the producing code
Example fix
// before
Map<Integer, Float> sparse = oneBased.entrySet().stream()
.collect(toMap(e -> e.getKey() - 1, Map.Entry::getValue)); // -1 when key==0
// after
Map<Integer, Float> sparse = new HashMap<>();
oneBased.forEach((k, v) -> { if (k - 1 >= 0) sparse.put(k - 1, v); }); Defensive patterns
Strategy: validation
Validate before calling
boolean nonNegativeIndexes(Map<Integer, ?> m) {
return m.keySet().stream().allMatch(k -> k != null && k >= 0);
}
if (!nonNegativeIndexes(sparseVector)) { throw new IllegalArgumentException("sparse vector indexes must be >= 0"); } Try / catch
try {
return VectorUtils.convertSparseVectorToFloatArray(sparse);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid sparse vector index: " + e.getMessage(), e);
} Prevention
- Audit 1-based vs 0-based index conversions (double conversion produces -1)
- Validate index ranges at data ingestion time
- Keep key size under the 1,000,000 cap or use dense arrays for large vectors
- Add boundary tests with index 0 and empty maps
When it happens
Trigger: A sparse vector map containing a negative Integer key, e.g. built by code that computed index-1 offsets or parsed signed values from input data.
Common situations: Downstream code subtracting 1 from 1-based indexes to make them 0-based when data was already 0-based, yielding -1; user-supplied data containing negative positions; bad parsers emitting negative placeholder keys.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- CREATE_INDEX_ERROR
- Condition operator must not be null
- Invalid metalake table id:
- Table URL cannot be null or empty
- Invalid table URL format: '%s'. Expected format: http://host
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/c75546666197ee7b.
Report an issue: GitHub.