redis/jedis · error · IllegalArgumentException
HashImport ' ' expects values but got
Error message
HashImport '<name>' expects <size> values but got <valueCount>
What it means
HashImportSupport.checkArgs enforces that the number of values passed to a hash-import call exactly matches the declared size of the HashImport fieldset. If the caller supplies fewer or more values than the fieldset was created with, IllegalArgumentException is thrown before anything is sent to Redis. This protects against desynchronized field/value pairing.
Solutions
- Ensure the values collection length equals fieldset.size() before the call (values.size() == fieldset.size())
- Rebuild the fieldset from the same source data as the values so they stay in sync
- Log both fieldset.size() and values.size() at the call site to find where they diverge
Example fix
// before
List<String> values = rawValues.stream().filter(Objects::nonNull).collect(toList());
jedis.himport(namespace, key, fieldset, values); // expects fieldset.size(), got fewer
// after
List<String> values = rawValues.stream().filter(Objects::nonNull).collect(toList());
if (values.size() != fieldset.size()) {
throw new IllegalArgumentException("values/fieldset mismatch: " + values.size() + " vs " + fieldset.size());
}
jedis.himport(namespace, key, fieldset, values); Defensive patterns
Strategy: validation
Validate before calling
if (values.size() != fieldset.size()) {
throw new IllegalArgumentException("expected " + fieldset.size() + " values, got " + values.size());
} Try / catch
try {
hashImportCall(fieldset, values);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("expects")) {
log.error("fieldset/values count mismatch: {}", e.getMessage());
}
throw e;
} Prevention
- Derive the values collection from the same data structure that built the fieldset
- Filter/normalize both sides together, never one after the fieldset was sized
- Assert equality of counts in tests covering the import path
When it happens
Trigger: Calling a hash-import API with a values array/collection whose length differs from fieldset.size() — e.g. the fieldset declares 5 hash fields but the caller passes 4 or 6 values in the corresponding varargs/Collection.
Common situations: Building the fieldset and the value list from different data sources that drifted out of sync; filtering nulls out of the values list after the fieldset was constructed; off-by-one bugs when appending a new field to one side only.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- HashImport ' ' has been discarded
- Cluster mode only supports SCAN command with MATCH pattern…
- null is not a valid argument.
- Failed to create socket.
- HashImport fields must be non-null and non-empty
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/aae4fcd089b26818.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/HashImportSupport.java:22
* {@code HIMPORT SET} helpers: client-side argument validation, and the per-connection
* prepare-before-use that a {@code himportSet} {@link CommandObject}'s
* {@linkplain CommandObject#getPreProcessHooks() pre-process hook} runs. The hook is invoked by
* {@link Connection#executeCommand(CommandObject)} once the {@code CommandExecutor} has picked a
* connection — so retry / cluster redirection / failover stay in force — injecting a
* {@code PREPARE} on that connection just before the {@code SET} when the fieldset is not yet
* prepared there.
*/
final class HashImportSupport {
private HashImportSupport() {
}
static void checkArgs(HashImport fieldset, int valueCount) {
if (fieldset.isDiscarded()) {
throw new IllegalStateException("HashImport '" + fieldset.name() + "' has been discarded");
}
if (valueCount != fieldset.size()) {
throw new IllegalArgumentException("HashImport '" + fieldset.name() + "' expects "
+ fieldset.size() + " values but got " + valueCount);
}
}
/**
* Prepare-before-use: if {@code fieldset} is not yet prepared on {@code connection}, send
* {@code HIMPORT PREPARE} and record it in the connection's note. The PREPARE is built here, only
* when actually needed — the common already-prepared case allocates nothing. The caller
* must own the connection.
*/
static void prepareBeforeUse(Connection connection, HashImport fieldset) {
if (!connection.himportState().isPrepared(fieldset.name())) {
connection.executeCommand(new CommandArguments(Protocol.Command.HIMPORT)
.add(Protocol.Keyword.PREPARE).add(fieldset.name()).addObjects(fieldset.fields()));
markPrepared(connection, fieldset);
}
}
View on GitHub (pinned to 6dac31d4c2)