apache/beam · error · RuntimeException

Unexpected kind: ${kind}

Error message

Unexpected kind: ${kind}

What it means

Group.toCombine (hot key fanout handling) supports only NUMBER and FUNCTION kinds for the per-key fanout. Any other HotKeyFanout kind hits the default branch and throws, indicating an unrecognized enumeration value.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/transforms/Group.java:1285

        Field outputField) {
      return toBuilder()
          .setSchemaAggregateFn(
              getSchemaAggregateFn().aggregateFields(fieldsToAggregate, false, fn, outputField))
          .build();
    }

    PTransform<PCollection<KV<Row, Row>>, PCollection<KV<Row, Row>>> getCombineTransform(
        Schema schema) {
      SchemaAggregateFn.Inner fn = getSchemaAggregateFn().withSchema(schema);
      @Nullable Fanout fanout = getFanout();
      if (fanout != null) {
        switch (fanout.getKind()) {
          case NUMBER:
            return Combine.<Row, Row, Row>perKey(fn).withHotKeyFanout(fanout.getNumber());
          case FUNCTION:
            return Combine.<Row, Row, Row>perKey(fn).withHotKeyFanout(fanout.getFunction());
          default:
            throw new RuntimeException("Unexpected kind: " + fanout.getKind());
        }
      }
      return getFewKeys() ? Combine.fewKeys(fn) : Combine.perKey(fn);
    }

    @Override
    public PCollection<Row> expand(PCollection<InputT> input) {

      Schema keySchema = getByFields().getKeySchema(input.getSchema());
      Schema outputSchema =
          Schema.builder()
              .addRowField(getKeyField(), keySchema)
              .addRowField(getValueField(), getSchemaAggregateFn().getOutputSchema())
              .build();

      return input
          .apply("ToKvs", getByFields().getToKV())
          .apply("Combine", getCombineTransform(input.getSchema()))

View on GitHub (pinned to 12126d8942)

Solutions

  1. Use only withHotKeyFanout(int) or withHotKeyFanout(SerializableFunction) variants.
  2. If building programmatically, ensure the fanout object's kind matches one of the two supported cases.
  3. Check Beam version consistency between pipeline construction and runner; a mismatched enum decoding can cause this.
  4. If hit with standard API usage, report a Beam bug with a reproducing pipeline.

Example fix

// before
fanout of unrecognized kind passed into Group.combine
// after
.apply(Group.byFieldNames("key").combineFields(fn).withHotKeyFanout(2))
Defensive patterns

Strategy: validation

Validate before calling

if (fanout.getKind() != NUMBER && fanout.getKind() != FUNCTION) throw new IllegalArgumentException("Unsupported hot key fanout kind: " + fanout.getKind());

Try / catch

try { return combineWithFanout(fanout); } catch (RuntimeException e) { if (e.getMessage().startsWith("Unexpected kind:")) { /* fall back to non-fanout combine */ } throw e; }

Prevention

When it happens

Trigger: Calling withHotKeyFanout with a value whose getKind() is neither NUMBER nor FUNCTION — practically this arises when a serialized/constructed fanout carries an unexpected kind enum, e.g. via custom Row encoding of Combine.PerKey options.

Common situations: Rare; typically encountered when programmatically building Group.byFieldNames(...).combining per-key options or after serialization corruption / version mismatch of pipeline options encoding the fanout kind.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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