apache/iceberg · error · IllegalArgumentException
Unexpected command: command
Error message
Unexpected command: command
What it means
SparkWriteConf.copyOnWriteDistributionMode() maps a row-level Command (DELETE, UPDATE, MERGE) to its copy-on-write distribution mode. Any Command outside that enum set is unexpected and throws IllegalArgumentException — an internal invariant/default-case guard.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkWriteConf.java:373
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());
}
@VisibleForTestingView on GitHub (pinned to 86d9c8fc54)
Solutions
- Only pass DELETE, UPDATE, or MERGE to this method; route other commands to their dedicated configuration methods (e.g. appendDistributionMode for writes)
- If a new Command value exists, upgrade the Iceberg Spark module so it is handled
- In custom code, switch on command yourself and only delegate supported values
Example fix
// before
DistributionMode mode = writeConf.copyOnWriteDistributionMode(command);
// after
if (command == Command.DELETE || command == Command.UPDATE || command == Command.MERGE) {
DistributionMode mode = writeConf.copyOnWriteDistributionMode(command);
} Defensive patterns
Strategy: validation
Validate before calling
if (command == null || (command != Command.DELETE && command != Command.UPDATE && command != Command.MERGE)) {
throw new IllegalArgumentException("copyOnWriteDistributionMode requires DELETE/UPDATE/MERGE");
} Type guard
boolean isRowLevelCommand = command == Command.DELETE || command == Command.UPDATE || command == Command.MERGE;
Try / catch
try {
mode = writeConf.copyOnWriteDistributionMode(command);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Unsupported command for CoW planning: " + command, e);
} Prevention
- Only pass row-level Command values to this method
- When adding new Command enum values, update all SparkWriteConf mode methods
- Switch on command explicitly and delegate each command to its own config method
When it happens
Trigger: Calling copyOnWriteDistributionMode() (directly or via copyOnWriteRequirements/checkMode) with a Command value that is not DELETE, UPDATE, or MERGE — e.g. a Command overwrite/insert variant or null.
Common situations: Custom Spark extensions or tests constructing SparkWriteConf and passing their own command; new Command enum values added upstream not yet handled by this distribution-mode method.
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
- Unsupported distribution mode: mode
- Unexpected distribution mode: mode
- Unsupported distribution mode:
- Unexpected command: ${command}
- Unsupported distribution mode: ${mode}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/426f5d665ccb1753.
Report an issue: GitHub.