apache/iceberg · error · IllegalArgumentException

Unexpected command:

Error message

Unexpected command: 

What it means

SparkWriteConf.copyOnWriteDistributionMode resolves the distribution mode for a copy-on-write write based on the RowLevelCommand (DELETE, UPDATE, MERGE). If the command is none of these, it throws IllegalArgumentException("Unexpected command: " + command), signaling a programming error rather than user misconfiguration - the command enum was extended or an unexpected value was passed.

Solutions

  1. Ensure all Iceberg modules are the same version so Command enums and SparkWriteConf branches match
  2. Only call copyOnWriteDistributionMode for row-level commands (DELETE/UPDATE/MERGE); route other commands elsewhere
  3. If a new Command constant was introduced, update the switch to handle it

Example fix

// before
DistributionMode mode = writeConf.copyOnWriteDistributionMode(Command.INSERT); // throws
// after
if (command == Command.INSERT) {
  mode = writeConf.distributionMode(); // append path
} else {
  mode = writeConf.copyOnWriteDistributionMode(command);
}
Defensive patterns

Strategy: validation

Validate before calling

if (command != Command.DELETE && command != Command.UPDATE && command != Command.MERGE) {
  throw new IllegalArgumentException("CoW distribution mode requires DELETE/UPDATE/MERGE, got: " + command);
}

Type guard

boolean isRowLevelCommand(Command c) {
  return c == Command.DELETE || c == Command.UPDATE || c == Command.MERGE;
}

Try / catch

try {
  mode = writeConf.copyOnWriteDistributionMode(command);
} catch (IllegalArgumentException e) {
  LOG.warn("Unexpected command {}, defaulting distribution mode", command, e);
  mode = writeConf.distributionMode();
}

Prevention

When it happens

Trigger: Passing a Command value other than DELETE, UPDATE, or MERGE (e.g. Command.INSERT or a newly added enum constant) into copyOnWriteDistributionMode via the write-conf resolution path.

Common situations: Upgrading Iceberg where a new RowLevelCommand constant was added but SparkWriteConf branches were not updated (version mismatch between modules); custom code invoking the conf method with an unexpected command.

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

Appendix: source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkWriteConf.java:369

    return SparkWriteUtil.copyOnWriteRequirements(
        table,
        command,
        copyOnWriteDistributionMode(command),
        fanoutWriterEnabled(),
        dataAdvisoryPartitionSize());
  }

  @VisibleForTesting
  DistributionMode copyOnWriteDistributionMode(Command command) {
    switch (command) {
      case DELETE:
        return deleteDistributionMode();
      case UPDATE:
        return updateDistributionMode();
      case MERGE:
        return copyOnWriteMergeDistributionMode();
      default:
        throw new IllegalArgumentException("Unexpected command: " + command);
    }
  }

  public SparkWriteRequirements positionDeltaRequirements(Command command) {
    if (ignoreTableDistributionAndOrdering()) {
      LOG.info("Skipping distribution/ordering: disabled per job configuration");
      return SparkWriteRequirements.EMPTY;
    }

    return SparkWriteUtil.positionDeltaRequirements(
        table,
        command,
        positionDeltaDistributionMode(command),
        fanoutWriterEnabled(),
        command == DELETE ? deleteAdvisoryPartitionSize() : dataAdvisoryPartitionSize());
  }

  @VisibleForTesting

View on GitHub (pinned to 86d9c8fc54)