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 is the same misconfiguration as in the Java source RedisCountStoreBolt: the counting bolt only implements Redis HINCRBY over a hash, so when the RedisStoreMapper's RedisDataTypeDescription declares anything other than HASH, process() throws this IllegalArgumentException, reports the error to the topology, and fails the tuple. The snippet here appears in the project's Chinese-language notes (Storm集成Redis详解.md) demonstrating a hand-written count bolt, so hitting it usually means the demo mapper was configured for a non-hash type.
Source
Thrown at notes/Storm集成Redis详解.md:589
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
- In the mapper used with the count bolt, return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, "WORD_COUNT") (any descriptive additionalKey works as the hash's key).
- Keep two distinct mapper classes: one for RedisStoreBolt (multi-type) and one for RedisCountStoreBolt (HASH-only) so the wrong one cannot be wired in silently.
- Add a constructor-time check in the custom bolt: if (dataTypeDescription.getDataType() != HASH) throw ... so the topology fails at submission, not on the first tuple.
- If a non-hash counter is required, switch to RedisStoreBolt with SORTED_SET and use ZINCRBY semantics via a custom bolt, not this HINCRBY-only implementation.
Example fix
// before
public class MyCountMapper implements RedisStoreMapper {
public RedisDataTypeDescription getDataTypeDescription() {
return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.STRING, null);
}
}
// after
public class MyCountMapper implements RedisStoreMapper {
public RedisDataTypeDescription getDataTypeDescription() {
return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, "WORD_COUNT");
}
} Defensive patterns
Strategy: validation
Validate before calling
RedisDataTypeDescription d = storeMapper.getDataTypeDescription();
if (d == null || d.getDataType() != RedisDataTypeDescription.RedisDataType.HASH) {
throw new IllegalArgumentException(
"RedisCountStoreBolt requires HASH, got: " + (d == null ? "null" : d.getDataType()));
} Type guard
boolean isUsableForCountBolt(org.apache.storm.redis.common.mapper.RedisStoreMapper mapper) {
RedisDataTypeDescription d = mapper.getDataTypeDescription();
return d != null
&& d.getDataType() == org.apache.storm.redis.common.mapper.RedisDataTypeDescription.RedisDataType.HASH;
} Try / catch
// Fail fast at topology build time instead of relying on the per-tuple catch:
if (!isUsableForCountBolt(storeMapper)) {
throw new IllegalStateException("Use a HASH-typed mapper with RedisCountStoreBolt; "
+ "got: " + storeMapper.getDataTypeDescription().getDataType());
} Prevention
- When following tutorial code, keep the mapper class paired with the bolt section it belongs to; name them accordingly (WordCountStoreMapper for the count bolt).
- Assert HASH in the bolt constructor or prepare() so a wrong mapper fails the topology at launch.
- Cover the bolt with a one-tuple LocalCluster integration test; this error only appears once real tuples flow.
- Document on the mapper class which bolts it may be used with.
When it happens
Trigger: Following the notes' example but building the RedisStoreMapper with RedisDataTypeDescription.RedisDataType.STRING / SORTED_SET / HYPER_LOG_LOG / GEO instead of HASH; or reusing a mapper written for the notes' RedisStoreBolt section (which supports those types) inside the RedisCountStoreBolt section. The throw happens on the first processed tuple, inside the else branch after the HASH check fails.
Common situations: Working through this repo's tutorial and copy-pasting a mapper from the store-bolt section into the count-bolt topology; adapting the demo to a different Redis structure without editing the count bolt's process(); version drift between the notes' code and the actual storm-redis API constants used in the mapper.
Related errors
- Cannot process such data type for Count: ${dataType}
- Jedis configuration not found
- Cannot process such data type: ${dataType}
- value structure should be longitude:latitude
AI-assisted analysis of heibaiying/BigData-Notes@3898939aca (2026-08-14).
Data as JSON: /api/errors/704e50116cade4d9.
Report an issue: GitHub.