nathanmarz/storm · error · IllegalArgumentException

Fields order must be same length as pointers map

Error message

Fields order must be same length as pointers map

What it means

ValuePointer.buildIndex builds a positional index mapping field names to tuple value locations. It requires the ordered Fields list and the pointer map to describe exactly the same field set; a size mismatch means the two views disagree, so it throws IllegalArgumentException.

Solutions

  1. Verify the Fields argument matches exactly the declared output fields of the preceding operation
  2. Use TridentUtils/fields validation or print stream.getOutputFields() to compare before wiring
  3. Fix upstream function declarations so the number of emitted values equals declared fields

Example fix

// before
stream.each(new Fields("a", "b", "c"), new MyFunc(), new Fields("out"))
// after  (upstream only declares a, b)
stream.each(new Fields("a", "b"), new MyFunc(), new Fields("out"))
Defensive patterns

Strategy: validation

Validate before calling

if (fieldsOrder.size() != pointers.size()) {
  throw new IllegalArgumentException("fieldsOrder and pointers must describe the same fields");
}

Try / catch

try {
  ValuePointer[] idx = ValuePointer.buildIndex(fieldsOrder, pointers);
} catch (IllegalArgumentException e) {
  LOG.error("Field selector does not match declared output fields", e);
}

Prevention

When it happens

Trigger: Internal Trident wiring where the Fields order passed (e.g. from a projection/each) contains a different number of fields than the ValuePointer map built from the upstream output — usually triggered by a user-supplied Fields selector that doesn't match declared output fields.

Common situations: Selecting fields in an each/project that don't exist or number differently from the function's declared fields; merging streams whose declarations diverged.

Related errors


AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12). Data as JSON: /api/errors/6cbb9f2cbf32b4c2. Report an issue: GitHub.

Appendix: source

Thrown at storm-core/src/jvm/storm/trident/tuple/ValuePointer.java:37

import backtype.storm.tuple.Fields;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.builder.ToStringBuilder;

public class ValuePointer {
    public static Map<String, ValuePointer> buildFieldIndex(ValuePointer[] pointers) {
        Map<String, ValuePointer> ret = new HashMap<String, ValuePointer>();
        for(ValuePointer ptr: pointers) {
            ret.put(ptr.field, ptr);
        }
        return ret;        
    }

    public static ValuePointer[] buildIndex(Fields fieldsOrder, Map<String, ValuePointer> pointers) {
        if(fieldsOrder.size()!=pointers.size()) {
            throw new IllegalArgumentException("Fields order must be same length as pointers map");
        }
        ValuePointer[] ret = new ValuePointer[pointers.size()];
        List<String> flist = fieldsOrder.toList();
        for(int i=0; i<fieldsOrder.size(); i++) {
            ret[i] = pointers.get(fieldsOrder.get(i));
        }
        return ret;
    }    
    
    public int delegateIndex;
    protected int index;
    protected String field;
    
    public ValuePointer(int delegateIndex, int index, String field) {
        this.delegateIndex = delegateIndex;
        this.index = index;
        this.field = field;
    }

View on GitHub (pinned to cdb116e942)