apache/beam · error · IllegalStateException

No fields were set for input ${tag}

Error message

No fields were set for input ${tag}

What it means

CoGroup.from builds the transform's key schemas by looking up, for each input PCollection tag, the FieldAccessDescriptor supplied via join clauses. If a tag in the PCollectionTuple has no corresponding field descriptor, it throws IllegalStateException, since every input must define its join key fields.

Source

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

              .map(TupleTag::getId)
              .sorted()
              .collect(Collectors.toList());

      // Keep this in a TreeMap so that it's sorted. This way we get a deterministic output
      // schema.
      TreeMap<String, Schema> componentSchemas = Maps.newTreeMap();

      Map<String, PCollectionView<Map<Row, Iterable<Row>>>> sideInputs = Maps.newHashMap();
      Map<Integer, String> tagToKeyedTag = Maps.newHashMap();
      Schema keySchema = null;
      for (Map.Entry<TupleTag<?>, PCollection<?>> entry : input.getAll().entrySet()) {
        String tag = entry.getKey().getId();
        PCollection<?> pc = entry.getValue();
        Schema schema = pc.getSchema();
        componentSchemas.put(tag, schema);
        FieldAccessDescriptor fieldAccessDescriptor = getFieldAccessDescriptor.apply(tag);
        if (fieldAccessDescriptor == null) {
          throw new IllegalStateException("No fields were set for input " + tag);
        }
        // Resolve the key schema, keeping the fields in the order specified by the user.
        // Otherwise, if different field names are specified for different PCollections, they
        // might not match up.
        // The key schema contains the field names from the first PCollection specified.
        FieldAccessDescriptor resolved = fieldAccessDescriptor.resolve(schema);
        Schema currentKeySchema = SelectHelpers.getOutputSchema(schema, resolved);
        if (keySchema == null) {
          keySchema = currentKeySchema;
        } else {
          keySchema = SchemaUtils.mergeWideningNullable(keySchema, currentKeySchema);
        }
      }
      // Second loop so we can widen the keySchema with every input before using it
      for (Map.Entry<TupleTag<?>, PCollection<?>> entry : input.getAll().entrySet()) {
        String tag = entry.getKey().getId();
        int tagIndex = sortedTags.indexOf(tag);
        PCollection<?> pc = entry.getValue();

View on GitHub (pinned to 12126d8942)

Solutions

  1. Add a join(tag, By.field(...)) clause for every tag present in the PCollectionTuple.
  2. Verify tag ids: TupleTag.getId() must exactly match the tag strings used in join() calls.
  3. Use the global byFields(...) variant if all inputs should use the same key fields, instead of per-tag clauses.
  4. Print input.getAll().keySet() and the join args map and diff them before building the transform.

Example fix

// before (tag "c" in tuple, no clause)
CoGroup join = CoGroup
    .join("a", By.field("key")).join("b", By.field("key"))
    .from(tuple); // throws: no fields for "c"
// after
CoGroup join = CoGroup
    .join("a", By.field("key")).join("b", By.field("key"))
    .join("c", By.field("key"))
    .from(tuple);
Defensive patterns

Strategy: validation

Validate before calling

Set<String> tags = tuple.getAll().keySet().stream().map(TupleTag::getId).collect(Collectors.toSet());
Set<String> joined = joinArgsMap.keySet();
if (!tags.equals(joined)) throw new IllegalStateException("missing join clauses for tags: " + Sets.difference(tags, joined));

Try / catch

try { CoGroup g = builder.from(tuple); } catch (IllegalStateException e) { if (e.getMessage().startsWith("No fields were set for input")) { /* add missing join(tag,...) */ } else throw e; }

Prevention

When it happens

Trigger: Constructing CoGroup via CoGroup.from(tuple) where the Impl's join fields were set with byFieldDescriptors (a map keyed by tag) that is missing an entry for one of the tuple's tags — e.g. joins specified for tags 'a' and 'b' but the tuple also contains tag 'c'.

Common situations: Forgetting a per-tag .join(tag, By.field(...)) call before expanding; adding a third input PCollection to the tuple without adding a matching join clause; tag name typos (TupleTag id differs from the string used in join).

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


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