{"record":{"id":"b1089729e41adfd1","repo":"heibaiying/BigData-Notes","slug":"cannot-process-such-data-type-for-count-datatyp","errorCode":null,"errorMessage":"Cannot process such data type for Count: ${dataType}","messagePattern":"Cannot process such data type for Count: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"code/Storm/storm-redis-integration/src/main/java/com/heibaiying/component/RedisCountStoreBolt.java","lineNumber":40,"sourceCode":"        super(config);\n        this.storeMapper = storeMapper;\n        RedisDataTypeDescription dataTypeDescription = storeMapper.getDataTypeDescription();\n        this.dataType = dataTypeDescription.getDataType();\n        this.additionalKey = dataTypeDescription.getAdditionalKey();\n    }\n\n    @Override\n    protected void process(Tuple tuple) {\n        String key = storeMapper.getKeyFromTuple(tuple);\n        String value = storeMapper.getValueFromTuple(tuple);\n\n        JedisCommands jedisCommand = null;\n        try {\n            jedisCommand = getInstance();\n            if (dataType == RedisDataTypeDescription.RedisDataType.HASH) {\n                jedisCommand.hincrBy(additionalKey, key, Long.valueOf(value));\n            } else {\n                throw new IllegalArgumentException(\"Cannot process such data type for Count: \" + dataType);\n            }\n\n            collector.ack(tuple);\n        } catch (Exception e) {\n            this.collector.reportError(e);\n            this.collector.fail(tuple);\n        } finally {\n            returnInstance(jedisCommand);\n        }\n    }\n\n    @Override\n    public void declareOutputFields(OutputFieldsDeclarer declarer) {\n\n    }\n}","sourceCodeStart":22,"sourceCodeEnd":56,"githubUrl":"https://github.com/heibaiying/BigData-Notes/blob/3898939aca387c25b3eb4e51ef49dfccca8543ed/code/Storm/storm-redis-integration/src/main/java/com/heibaiying/component/RedisCountStoreBolt.java#L22-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (in WordCountStoreMapper or your RedisStoreMapper)\n@Override\npublic RedisDataTypeDescription getDataTypeDescription() {\n    return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.STRING, null);\n}\n\n// after\n@Override\npublic RedisDataTypeDescription getDataTypeDescription() {\n    return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, \"WORD_COUNT\");\n}","handlingStrategy":"validation","validationCode":"RedisDataTypeDescription.RedisDataType t = storeMapper.getDataTypeDescription().getDataType();\nif (t != RedisDataTypeDescription.RedisDataType.HASH) {\n    throw new IllegalArgumentException(\"RedisCountStoreBolt requires HASH data type, got: \" + t);\n}","typeGuard":"boolean isHashCountMapper(org.apache.storm.redis.common.mapper.RedisStoreMapper mapper) {\n    return mapper.getDataTypeDescription() != null\n        && mapper.getDataTypeDescription().getDataType()\n            == org.apache.storm.redis.common.mapper.RedisDataTypeDescription.RedisDataType.HASH;\n}","tryCatchPattern":"// The bolt already reports and fails the tuple; catch at topology-test level to surface the config bug:\ntry {\n    new RedisCountStoreBolt(jedisPoolConfig, mapper).prepare(stormConf, topologyContext, collector);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Cannot process such data type for Count\")) {\n        throw new IllegalStateException(\"Mapper must declare HASH for RedisCountStoreBolt\", e);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["storm","redis","jedis","illegalargumentexception","configuration","bolt"],"backgroundTag":null,"analyzedSha":"3898939aca387c25b3eb4e51ef49dfccca8543ed","analyzedAt":"2026-08-14T15:36:11.245Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}