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

  1. Set the mapper's data type description to HASH, e.g. return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, "WORD_COUNT") inside RedisStoreMapper.getDataTypeDescription().
  2. 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.
  3. 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.
  4. 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

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


AI-assisted analysis of heibaiying/BigData-Notes@3898939aca (2026-08-14). Data as JSON: /api/errors/b1089729e41adfd1. Report an issue: GitHub.