apache/beam · error · IllegalStateException

Unable to infer a coder for MapState and no Coder was specif

Error message

Unable to infer a coder for MapState and no Coder was specified. Please set a coder by either invoking StateSpecs.map(Coder<K> keyCoder, Coder<V> valueCoder) or by registering the coder in the Pipeline's CoderRegistry.

What it means

finishSpecifying on the MapState spec found keyCoder or valueCoder null: no coders were supplied via StateSpecs.map(keyCoder, valueCoder) and inference/offerCoders could not supply them by the time the spec was finalized. The map state spec's key/value types are the inputs at fault.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/state/StateSpecs.java:763

    public <ResultT> ResultT match(Cases<ResultT> cases) {
      return cases.dispatchMap(keyCoder, valueCoder);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void offerCoders(Coder[] coders) {
      if (this.keyCoder == null && coders[0] != null) {
        this.keyCoder = (Coder<K>) coders[0];
      }
      if (this.valueCoder == null && coders[1] != null) {
        this.valueCoder = (Coder<V>) coders[1];
      }
    }

    @Override
    public void finishSpecifying() {
      if (keyCoder == null || valueCoder == null) {
        throw new IllegalStateException(
            "Unable to infer a coder for MapState and no Coder"
                + " was specified. Please set a coder by either invoking"
                + " StateSpecs.map(Coder<K> keyCoder, Coder<V> valueCoder) or by registering the"
                + " coder in the Pipeline's CoderRegistry.");
      }
    }

    @Override
    public boolean equals(@Nullable Object obj) {
      if (obj == this) {
        return true;
      }

      if (!(obj instanceof MapStateSpec)) {
        return false;
      }

      MapStateSpec<?, ?> that = (MapStateSpec<?, ?>) obj;

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass both coders: StateSpecs.map(keyCoder, valueCoder).
  2. Register coders for K and V in the pipeline's CoderRegistry.
  3. Use types with inferrable coders for keys and values.

Example fix

// before
MapStateSpec<String, Long> spec = StateSpecs.map();
// after
MapStateSpec<String, Long> spec = StateSpecs.map(StringUtf8Coder.of(), VarLongCoder.of());
Defensive patterns

Strategy: validation

Validate before calling

if (keyCoder == null || valueCoder == null) {
  throw new IllegalStateException("Supply StateSpecs.map(keyCoder, valueCoder) with explicit coders");
}

Try / catch

try {
  spec = StateSpecs.map();
} catch (IllegalStateException e) {
  if (e.getMessage().contains("MapState")) {
    spec = StateSpecs.map(keyCoder, valueCoder);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling StateSpecs.map() (no-arg overload) where inference fails for the key type K or the value type V.

Common situations: Maps keyed or valued by custom classes without registered coders; partial inference success (key inferred but value not) still triggers the error.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/415c000607d81141. Report an issue: GitHub.