nathanmarz/storm · error · IllegalArgumentException
Require input fields for each aggregator
Error message
Require input fields for each aggregator
What it means
ChainedAggregatorImpl combines N aggregators and needs one Fields input spec per aggregator so each can build its ProjectionFactory. If the aggs array and inputFields array lengths differ, the constructor throws this IllegalArgumentException immediately.
Solutions
- Provide exactly one Fields per aggregator in the inputFields array
- Verify both arrays have the same length before constructing (add an assertion in your builder code)
- Use ChainedAggregatorDeclarer high-level API instead of assembling ChainedAggregatorImpl manually
Example fix
// before
new ChainedAggregatorImpl(new Aggregator[]{a1, a2}, new Fields[]{f1}, fact);
// after
new ChainedAggregatorImpl(new Aggregator[]{a1, a2}, new Fields[]{f1, f2}, fact); Defensive patterns
Strategy: type-guard
Validate before calling
if (aggs.length != inputFields.length) {
throw new IllegalArgumentException("Need one Fields per aggregator: aggs=" + aggs.length + " fields=" + inputFields.length);
} Type guard
boolean inputFieldsMatch(Aggregator[] aggs, Fields[] fields) {
return aggs != null && fields != null && aggs.length == fields.length;
} Try / catch
try {
new ChainedAggregatorImpl(aggs, inputFields, fact);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("Require input fields for each aggregator")) {
throw new IllegalStateException("inputFields array must parallel aggs array", e);
} throw e;
} Prevention
- Always build aggs and inputFields together in a single loop
- Prefer ChainedAggregatorDeclarer over manual ChainedAggregatorImpl construction
- Assert equal lengths in custom builder helpers
When it happens
Trigger: Constructing ChainedAggregatorImpl directly, or via chained agg declarer paths, passing an Aggregator[] and Fields[] of different lengths (e.g. forgetting input fields for one aggregator).
Common situations: Low-level direct use of ChainedAggregatorImpl in custom Trident wiring; building custom composite operations and omitting a null/empty entry in the inputFields list.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Output fields for chained aggregators must be distinct
- Combiner state updater should receive a single tuple…
- Multireducer groupFields and inputFields must be the same…
- numBuckets must be >= 2
- Trying to select non-existent field
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/1d25d0b8c3d32c33.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/storm/trident/operation/impl/ChainedAggregatorImpl.java:44
import storm.trident.tuple.ComboList;
import storm.trident.tuple.TridentTuple;
import storm.trident.tuple.TridentTupleView;
import storm.trident.tuple.TridentTupleView.ProjectionFactory;
public class ChainedAggregatorImpl implements Aggregator<ChainedResult> {
Aggregator[] _aggs;
ProjectionFactory[] _inputFactories;
ComboList.Factory _fact;
Fields[] _inputFields;
public ChainedAggregatorImpl(Aggregator[] aggs, Fields[] inputFields, ComboList.Factory fact) {
_aggs = aggs;
_inputFields = inputFields;
_fact = fact;
if(_aggs.length!=_inputFields.length) {
throw new IllegalArgumentException("Require input fields for each aggregator");
}
}
public void prepare(Map conf, TridentOperationContext context) {
_inputFactories = new ProjectionFactory[_inputFields.length];
for(int i=0; i<_inputFields.length; i++) {
_inputFactories[i] = context.makeProjectionFactory(_inputFields[i]);
_aggs[i].prepare(conf, new TridentOperationContext(context, _inputFactories[i]));
}
}
public ChainedResult init(Object batchId, TridentCollector collector) {
ChainedResult initted = new ChainedResult(collector, _aggs.length);
for(int i=0; i<_aggs.length; i++) {
initted.objs[i] = _aggs[i].init(batchId, initted.collectors[i]);
}
return initted;
}View on GitHub (pinned to cdb116e942)