heibaiying/BigData-Notes · error · IllegalArgumentException
Cannot process such data type for Count: ${dataType}
Error message
Cannot process such data type for Count: ${dataType} What it means
This IllegalArgumentException is thrown by the custom RedisCountStoreBolt (based on Storm's AbstractRedisBolt) when the RedisDataTypeDescription returned by the RedisStoreMapper declares any data type other than HASH. The bolt's counting logic relies exclusively on Redis HINCRBY (hash field increment), so only the HASH data type is a valid configuration. The exception is thrown inside process(), caught, reported to the topology via collector.reportError(e), and the tuple is failed, so it surfaces in the Storm UI as a reported topology error and triggers replay/failure of the tuple.
Source
Thrown at code/Storm/storm-redis-integration/src/main/java/com/heibaiying/component/RedisCountStoreBolt.java:40
super(config);
this.storeMapper = storeMapper;
RedisDataTypeDescription dataTypeDescription = storeMapper.getDataTypeDescription();
this.dataType = dataTypeDescription.getDataType();
this.additionalKey = dataTypeDescription.getAdditionalKey();
}
@Override
protected void process(Tuple tuple) {
String key = storeMapper.getKeyFromTuple(tuple);
String value = storeMapper.getValueFromTuple(tuple);
JedisCommands jedisCommand = null;
try {
jedisCommand = getInstance();
if (dataType == RedisDataTypeDescription.RedisDataType.HASH) {
jedisCommand.hincrBy(additionalKey, key, Long.valueOf(value));
} else {
throw new IllegalArgumentException("Cannot process such data type for Count: " + dataType);
}
collector.ack(tuple);
} catch (Exception e) {
this.collector.reportError(e);
this.collector.fail(tuple);
} finally {
returnInstance(jedisCommand);
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
}View on GitHub (pinned to 3898939aca)
Solutions
- Set the mapper's data type description to HASH, e.g. return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, "WORD_COUNT") inside RedisStoreMapper.getDataTypeDescription().
- If you genuinely need to count into a non-hash structure, do not use this bolt: use RedisStoreBolt with an appropriate type or write custom process() logic (e.g. ZINCRBY for sorted sets) instead of allowing HINCRBY-only code to run.
- Fail fast: validate in the RedisCountStoreBolt constructor that dataType == HASH (throw immediately at topology submission time) rather than discovering the misconfiguration on the first tuple.
- Check the Storm UI 'Show system stats' / reported errors or worker logs to confirm this exact message and identify which bolt and mapper produced it.
Example fix
// before (in WordCountStoreMapper or your RedisStoreMapper)
@Override
public RedisDataTypeDescription getDataTypeDescription() {
return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.STRING, null);
}
// after
@Override
public RedisDataTypeDescription getDataTypeDescription() {
return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, "WORD_COUNT");
} Defensive patterns
Strategy: validation
Validate before calling
RedisDataTypeDescription.RedisDataType t = storeMapper.getDataTypeDescription().getDataType();
if (t != RedisDataTypeDescription.RedisDataType.HASH) {
throw new IllegalArgumentException("RedisCountStoreBolt requires HASH data type, got: " + t);
} Type guard
boolean isHashCountMapper(org.apache.storm.redis.common.mapper.RedisStoreMapper mapper) {
return mapper.getDataTypeDescription() != null
&& mapper.getDataTypeDescription().getDataType()
== org.apache.storm.redis.common.mapper.RedisDataTypeDescription.RedisDataType.HASH;
} Try / catch
// The bolt already reports and fails the tuple; catch at topology-test level to surface the config bug:
try {
new RedisCountStoreBolt(jedisPoolConfig, mapper).prepare(stormConf, topologyContext, collector);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Cannot process such data type for Count")) {
throw new IllegalStateException("Mapper must declare HASH for RedisCountStoreBolt", e);
}
throw e;
} Prevention
- Assert dataType == HASH once in the bolt constructor so misconfiguration fails at topology submission, not per-tuple.
- Keep dedicated HASH-only mapper classes for count bolts; never reuse multi-type store mappers with them.
- Add an integration test that runs one tuple through the bolt in LocalCluster before deploying to production.
When it happens
Trigger: Constructing RedisCountStoreBolt with a RedisStoreMapper whose getDataTypeDescription().getDataType() returns STRING, SORTED_SET, HYPER_LOG_LOG, GEO, or any type other than RedisDataTypeDescription.RedisDataType.HASH. The check happens per-tuple in process(): the moment the first tuple arrives, the else branch throws. Note the failure is delayed to runtime, not raised at topology construction.
Common situations: Copying a RedisStoreMapper built for RedisStoreBolt (which supports many data types) and reusing it in a counting bolt that only supports HASH; forgetting to call dataTypeDescription(new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, additionalKey)) on the mapper; refactoring from the stock RedisCountStoreBolt (which always uses HASH internally and takes no data type description) to a custom bolt and passing the wrong description; testing with a mapper configured for SORTED_SET/GEO from another example in the same project.
Related errors
- Jedis configuration not found
- Cannot process such data type: ${dataType}
- Cannot process such data type for Count: ${dataType}
- value structure should be longitude:latitude
AI-assisted analysis of heibaiying/BigData-Notes@3898939aca (2026-08-14).
Data as JSON: /api/errors/b1089729e41adfd1.
Report an issue: GitHub.