apache/iceberg · error · IllegalArgumentException

Unsupported command: " + command

Error message

Unsupported command: " + command

What it means

SparkRowLevelOperationBuilder.mode(Command) only supports the DELETE, UPDATE, and MERGE commands; any other command has no row-level mode configuration and fails with IllegalArgumentException. The mode is resolved from table properties like write.delete.mode / write.update.mode / write.merge.mode.

Solutions

  1. Only invoke the builder for DELETE, UPDATE, or MERGE commands.
  2. Add a case for the new command in SparkRowLevelOperationBuilder if extending support.
  3. Check the Spark/Iceberg version pairing; a new Spark command may not yet be supported by this Iceberg version.
  4. Set the appropriate write.<command>.mode table property for supported commands.

Example fix

// before
RowLevelOperationMode mode = builder.mode(anyCommand);
// after
if (command instanceof Delete || command instanceof Update || command instanceof MergeIntoTable) {
  RowLevelOperationMode mode = builder.mode(command);
}
Defensive patterns

Strategy: validation

Validate before calling

Set<Command> supported = Set.of(Delete.class, Update.class, MergeIntoTable.class); if (!supported.contains(command.getClass())) throw new IllegalArgumentException("unsupported: " + command);

Type guard

boolean supported = command instanceof Delete || command instanceof Update || command instanceof MergeIntoTable;

Try / catch

try { return builder.mode(command); } catch (IllegalArgumentException e) { return RowLevelOperationMode.COPY_ON_WRITE; }

Prevention

When it happens

Trigger: mode() is called with a Command value outside the switch (DELETE/UPDATE/MERGE), e.g. a custom or future Spark Command type passed to the row-level operation builder.

Common situations: Third-party commands routed into Iceberg's row-level operation support; Spark version upgrades introducing new Command kinds; custom extensions calling the builder.

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/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/027b3242bf117b1c. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/SparkRowLevelOperationBuilder.java:94

          new SparkPositionDeltaOperation(spark, table, snapshot, branch, info, isolationLevel);
    };
  }

  private RowLevelOperationMode mode(Map<String, String> properties, Command command) {
    String modeName;

    switch (command) {
      case DELETE:
        modeName = properties.getOrDefault(DELETE_MODE, DELETE_MODE_DEFAULT);
        break;
      case UPDATE:
        modeName = properties.getOrDefault(UPDATE_MODE, UPDATE_MODE_DEFAULT);
        break;
      case MERGE:
        modeName = properties.getOrDefault(MERGE_MODE, MERGE_MODE_DEFAULT);
        break;
      default:
        throw new IllegalArgumentException("Unsupported command: " + command);
    }

    return RowLevelOperationMode.fromName(modeName);
  }

  private IsolationLevel isolationLevel(Map<String, String> properties, Command command) {
    String levelName;

    switch (command) {
      case DELETE:
        levelName = properties.getOrDefault(DELETE_ISOLATION_LEVEL, DELETE_ISOLATION_LEVEL_DEFAULT);
        break;
      case UPDATE:
        levelName = properties.getOrDefault(UPDATE_ISOLATION_LEVEL, UPDATE_ISOLATION_LEVEL_DEFAULT);
        break;
      case MERGE:
        levelName = properties.getOrDefault(MERGE_ISOLATION_LEVEL, MERGE_ISOLATION_LEVEL_DEFAULT);
        break;

View on GitHub (pinned to 86d9c8fc54)