apache/beam · error · IllegalArgumentException

${resolved} references multiple fields.

Error message

${resolved} references multiple fields.

What it means

RenameFields renames exactly one field per RenamePair. After resolving the FieldAccessDescriptor against the schema, if it references multiple fields (e.g. a wildcard, qualifier matching several fields, or a multi-field descriptor), resolve() throws IllegalArgumentException since a rename must map a single field to a new name.

Source

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

  // Describes a single renameSchema rule
  @AutoValue
  abstract static class RenamePair implements Serializable {
    // The FieldAccessDescriptor describing the field to renameSchema. Must reference a singleton
    // field.
    abstract FieldAccessDescriptor getFieldAccessDescriptor();

    // The new name for the field.
    abstract String getNewName();

    static RenamePair of(FieldAccessDescriptor fieldAccessDescriptor, String newName) {
      return new AutoValue_RenameFields_RenamePair(fieldAccessDescriptor, newName);
    }

    RenamePair resolve(Schema schema) {
      FieldAccessDescriptor resolved = getFieldAccessDescriptor().resolve(schema);
      if (!resolved.referencesSingleField()) {
        throw new IllegalArgumentException(resolved + " references multiple fields.");
      }
      return RenamePair.of(resolved, getNewName());
    }
  }

  private static FieldType renameFieldType(
      FieldType inputType,
      Collection<RenamePair> renames,
      Map<UUID, Schema> renamedSchemasMap,
      Map<UUID, BitSet> nestedFieldRenamedMap) {
    if (renames.isEmpty()) {
      return inputType;
    }

    switch (inputType.getTypeName()) {
      case ROW:
        renameSchema(inputType.getRowSchema(), renames, renamedSchemasMap, nestedFieldRenamedMap);
        return FieldType.row(renamedSchemasMap.get(inputType.getRowSchema().getUUID()));

View on GitHub (pinned to 12126d8942)

Solutions

  1. Create one RenameField per field: withRenamedField("a", "newA").withRenamedField("b", "newB").
  2. Narrow the FieldAccessDescriptor so it references exactly one field (use referencesSingleField to check).
  3. Avoid wildcard/multi-field descriptors in rename specifications.
  4. Resolve the descriptor against the schema in tests before running the pipeline to catch multi-field matches early.

Example fix

// before
RenameFields.of(RenamePair.of(FieldAccessDescriptor.withFieldNames("a","b"), "x"))
// after
RenameFields.of(RenamePair.of(FieldAccessDescriptor.withFieldNames("a"), "x"))
            .and(RenamePair.of(FieldAccessDescriptor.withFieldNames("b"), "y"))
Defensive patterns

Strategy: validation

Validate before calling

FieldAccessDescriptor r = desc.resolve(schema); if (!r.referencesSingleField()) throw new IllegalArgumentException("Rename must reference exactly one field, got: " + r);

Type guard

boolean singleField(FieldAccessDescriptor d, Schema s) { return d.resolve(s).referencesSingleField(); }

Try / catch

try { pairs.resolve(schema); } catch (IllegalArgumentException e) { if (e.getMessage().endsWith("references multiple fields.")) { /* split the descriptor into per-field renames */ } throw e; }

Prevention

When it happens

Trigger: Building RenameField.create(...) with a FieldAccessDescriptor matching more than one field — e.g. By.field("a.*")-style or descriptors built with multiple fields via FieldAccessDescriptor.withFieldNames("a","b").

Common situations: Using a wildcard-ish or shared-prefix field spec expecting all matched fields to be renamed, or passing a multi-field descriptor to a single rename call instead of one rename per field.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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