apache/beam · error · RuntimeException

Unexpected mutation type [%s]: %s

Error message

Unexpected mutation type [%s]: %s

What it means

In BigtableWriteSchemaTransformProvider's inner apply (mutation-map based input), each mutation map's 'type' selects the Mutation to build. The default branch throws a RuntimeException with the unsupported type and the full mutation map when the type isn't a known one; note ofNullable(mutation.get("type")).get() will throw NoSuchElementException if 'type' is missing entirely.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableWriteSchemaTransformProvider.java:443

            break;
          case "DeleteFromFamily":
            bigtableMutation =
                Mutation.newBuilder()
                    .setDeleteFromFamily(
                        Mutation.DeleteFromFamily.newBuilder()
                            .setFamilyNameBytes(
                                ByteString.copyFrom(ofNullable(mutation.get("family_name")).get()))
                            .build())
                    .build();
            break;
          case "DeleteFromRow":
            bigtableMutation =
                Mutation.newBuilder()
                    .setDeleteFromRow(Mutation.DeleteFromRow.newBuilder().build())
                    .build();
            break;
          default:
            throw new RuntimeException(
                String.format(
                    "Unexpected mutation type [%s]: %s",
                    Arrays.toString(ofNullable(mutation.get("type")).get()), mutation));
        }
        mutations.add(bigtableMutation);
      }
      return KV.of(key, mutations);
    }
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Set 'type' in each mutation map to exactly one of SetCell, DeleteFamily, DeleteColumn, DeleteRow
  2. Guard for a missing 'type' key before calling the transform to get a clearer error than NoSuchElementException
  3. Log the full mutation map (included in the message) to identify and correct the bad record

Example fix

// before
Map<String, ByteString> mutation = ImmutableMap.of("Type", cellBytes); // wrong key/type
// after
Map<String, ByteString> mutation = ImmutableMap.of(
    "type", ByteString.copyFromUtf8("SetCell"),
    "family_name", ByteString.copyFromUtf8("cf"),
    "column_qualifier", ByteString.copyFromUtf8("cq"),
    "value", cellBytes);
Defensive patterns

Strategy: validation

Validate before calling

boolean validMutationMap(Map<String, ByteString> m) {
  ByteString t = m.get("type");
  return t != null && Set.of("SetCell","DeleteFamily","DeleteColumn","DeleteRow")
      .contains(t.toStringUtf8());
}

Type guard

boolean hasKnownType(Map<String, ByteString> mutation) {
  ByteString t = mutation.get("type");
  return t != null && switch (t.toStringUtf8()) {
    case "SetCell", "DeleteFamily", "DeleteColumn", "DeleteRow" -> true;
    default -> false;
  };
}

Try / catch

try {
  apply(mutations);
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("Unexpected mutation type")) {
    // fix or drop the mutation map logged in the message
  }
}

Prevention

When it happens

Trigger: Passing a mutation map with a 'type' key that is not SetCell/DeleteFamily/DeleteColumn/DeleteRow, or a map missing 'type' entirely (which triggers NoSuchElementException inside this error path).

Common situations: Programmatically generated mutation maps with typos in the type field; mixing user-authored mutation maps from different APIs; JSON/YAML configs with incorrect type names.

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/f6c86898b1498e31. Report an issue: GitHub.