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

  1. 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).
  2. 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.
  3. 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.
  4. 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 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


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