pentaho/pentaho-kettle · error · KettleStepException
Couldn't find field ' ' in row!
Error message
Couldn't find field '{0}' in row! What it means
The Set Value Field step failed to locate one of the configured field names in the incoming row's metadata. During processRow it calls outputRowMeta.indexOfValue(fieldName); a negative index means the field does not exist in the row stream, so the step cannot know where to write the replacement value and throws KettleStepException. This is almost always a transformation design/configuration mismatch rather than a runtime data problem.
Solutions
- Open the Set Value Field step dialog and re-select the 'Field' entry so it matches an actual field in the incoming stream (use 'Get Fields').
- Verify the upstream step that produces the field actually runs before Set Value Field and outputs it; preview the previous step to see the real row fields.
- If the field name uses ${VARIABLE} substitution, log environmentSubstitute output or hardcode the name to confirm the variable resolves to the expected field.
- If the field is optional by design, restructure the flow (e.g. use a User Defined Java Expression or Filter so the step only runs when the field exists).
Example fix
// before (field typed manually, may not exist) fieldName = "custmer_id"; // after (use exact upstream field name) fieldName = "customer_id";
Defensive patterns
Strategy: validation
Validate before calling
// Before running, verify all configured fields exist in the incoming row meta
for (String name : meta.getFieldName()) {
String resolved = environmentSubstitute(name);
if (transMeta.getPrevStepFields(stepMeta).indexOfValue(resolved) < 0) {
throw new IllegalStateException("Field not in row stream: " + resolved);
}
} Type guard
if (rowMeta.indexOfValue(fieldName) < 0) { return null; } // treat as absent field Try / catch
try {
trans.execute(null);
} catch (KettleStepException e) {
log.error("Set Value Field misconfigured: {}", e.getMessage()); // fix step field mapping
} Prevention
- Always pick fields from the dropdown / 'Get Fields' instead of typing them
- Preview the previous step after any upstream change
- Avoid variables in field names, or log their resolved values in a test run
- Re-save transformations after renaming upstream steps
When it happens
Trigger: processRow resolves data.indexOfField[i] = data.outputRowMeta.indexOfValue(environmentSubstitute(meta.getFieldName()[i])) at the start of processing; any configured field name that is not present in the row coming from the previous step (or a typo / renamed field / wrong variable value after substitution) yields indexOfValue < 0 and triggers the throw.
Common situations: The upstream step was renamed or removed and its output field disappeared; the field name contains a Kettle variable whose value resolves differently at runtime (e.g. on a slave server); the user typed the field name manually instead of picking it from the dropdown; copying the transformation between environments where upstream metadata changed.
Related errors
- At this time we don't support the use of multiple cluster…
- Erreur finding step [
- FieldsChangeSequence.Log.CanNotFindField
- GetFilesRowsCount.Exception.CouldnotFindField
- LDIFInput.Exception.CouldnotFindField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/cb50002375704298.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/setvaluefield/SetValueField.java:82
meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
metaStore );
data.indexOfField = new int[meta.getFieldName().length];
data.indexOfReplaceByValue = new int[meta.getFieldName().length];
for ( int i = 0; i < meta.getFieldName().length; i++ ) {
// Check if this field was specified only one time
for ( int j = 0; j < meta.getFieldName().length; j++ ) {
if ( meta.getFieldName()[j].equals( meta.getFieldName()[i] ) ) {
if ( j != i ) {
throw new KettleException( BaseMessages.getString(
PKG, "SetValueField.Log.FieldSpecifiedMoreThatOne", meta.getFieldName()[i], "" + i, "" + j ) );
}
}
}
data.indexOfField[i] = data.outputRowMeta.indexOfValue( environmentSubstitute( meta.getFieldName()[i] ) );
if ( data.indexOfField[i] < 0 ) {
throw new KettleStepException( BaseMessages.getString(
PKG, "SetValueField.Log.CouldNotFindFieldInRow", meta.getFieldName()[i] ) );
}
String sourceField = environmentSubstitute(
meta.getReplaceByFieldValue() != null && meta.getReplaceByFieldValue().length > 0
? meta.getReplaceByFieldValue()[i] : null
);
if ( Utils.isEmpty( sourceField ) ) {
throw new KettleStepException( BaseMessages.getString(
PKG, "SetValueField.Log.ReplaceByValueFieldMissing", "" + i ) );
}
data.indexOfReplaceByValue[i] = data.outputRowMeta.indexOfValue( sourceField );
if ( data.indexOfReplaceByValue[i] < 0 ) {
throw new KettleStepException( BaseMessages.getString(
PKG, "SetValueField.Log.CouldNotFindFieldInRow", sourceField ) );
}
// Compare fields type
ValueMetaInterface SourceValue = getInputRowMeta().getValueMeta( data.indexOfField[i] );
ValueMetaInterface ReplaceByValue = getInputRowMeta().getValueMeta( data.indexOfReplaceByValue[i] );View on GitHub (pinned to f3058517a1)