pentaho/pentaho-kettle · error · KettleRowException
BaseStep.SafeMode.Exception.MixingLayout
BaseStep.SafeMode.Exception.MixingLayout
Error message
BaseStep.SafeMode.Exception.MixingLayout
What it means
safeModeChecking walks fields positionally; if the field name at position i in the incoming row does not (case-insensitively) match the reference row's field name at i, KettleRowException is thrown. Same field count but fields are in different order or named differently — the row layouts are being mixed.
Solutions
- Make the producing step emit fields in a deterministic order (use a List, not a Map, for field construction).
- Insert a 'Select values' step before the failing step to enforce a canonical field order.
- Check for multiple previous hops feeding the step and align both branches' column order.
- If a plugin upgrade reordered columns, pin the previous plugin version or update downstream mappings.
Example fix
// before Map<String,Object> m = new HashMap<>(); // iteration order varies // after List<Object> ordered = Arrays.asList(name, value); // fixed positional order
Defensive patterns
Strategy: validation
Validate before calling
for (int i = 0; i < rowMeta.size(); i++) {
if (!rowMeta.getValueMeta(i).getName().equalsIgnoreCase(referenceMeta.getValueMeta(i).getName()))
throw new IllegalStateException("Field order mismatch at position " + i);
} Try / catch
try { trans.startThreads(); } catch (KettleException e) { if (e.getCause() instanceof KettleRowException && e.getCause().getMessage().contains("MixingLayout")) { logError("Field order differs between rows"); } throw e; } Prevention
- Build rows from ordered collections (List), never HashMap iteration
- Use a Select values step to canonicalize field order after merges
- Keep both branches of a merge aligned on column order
- Re-check plugins after upgrades for changed field order
When it happens
Trigger: Safe mode enabled; rows of equal size but with reordered or renamed fields arrive at a step after the reference row was captured (e.g. a step emits [a,b] first then [b,a]).
Common situations: Steps that build rows from a HashMap/unordered Map whose iteration order varies; two branches of a transformation merged with different column orders into the same step; a plugin version change that reordered output fields.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- BaseStep.SafeMode.Exception.DoubleFieldnames
- BaseStep.SafeMode.Exception.MixingStorageTypes
- BaseStep.SafeMode.Exception.MixingTypes
- BaseStep.SafeMode.Exception.VaryingSize
- SalesforceUpsert.FieldNotFound
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/75df9853c7b80b34.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/step/BaseStep.java:2180
* @param rowMeta the row meta
* @throws KettleRowException the kettle row exception
*/
public static void safeModeChecking( RowMetaInterface referenceRowMeta, RowMetaInterface rowMeta )
throws KettleRowException {
// See if the row we got has the same layout as the reference row.
// First check the number of fields
//
if ( referenceRowMeta.size() != rowMeta.size() ) {
throw new KettleRowException( BaseMessages.getString( PKG, "BaseStep.SafeMode.Exception.VaryingSize", ""
+ referenceRowMeta.size(), "" + rowMeta.size(), rowMeta.toString() ) );
} else {
// Check field by field for the position of the names...
for ( int i = 0; i < referenceRowMeta.size(); i++ ) {
ValueMetaInterface referenceValue = referenceRowMeta.getValueMeta( i );
ValueMetaInterface compareValue = rowMeta.getValueMeta( i );
if ( !referenceValue.getName().equalsIgnoreCase( compareValue.getName() ) ) {
throw new KettleRowException( BaseMessages.getString(
PKG, "BaseStep.SafeMode.Exception.MixingLayout", "" + ( i + 1 ), referenceValue.getName()
+ " " + referenceValue.toStringMeta(), compareValue.getName()
+ " " + compareValue.toStringMeta() ) );
}
if ( referenceValue.getType() != compareValue.getType() ) {
throw new KettleRowException( BaseMessages.getString( PKG, "BaseStep.SafeMode.Exception.MixingTypes", ""
+ ( i + 1 ), referenceValue.getName() + " " + referenceValue.toStringMeta(), compareValue.getName()
+ " " + compareValue.toStringMeta() ) );
}
if ( referenceValue.getStorageType() != compareValue.getStorageType() ) {
throw new KettleRowException( BaseMessages.getString(
PKG, "BaseStep.SafeMode.Exception.MixingStorageTypes", "" + ( i + 1 ), referenceValue.getName()
+ " " + referenceValue.toStringMeta(), compareValue.getName()
+ " " + compareValue.toStringMeta() ) );
}
}View on GitHub (pinned to f3058517a1)