pentaho/pentaho-kettle · error · KettleStepException
ScriptValuesMetaMod.Exception.FieldToReplaceNotFound
Error message
ScriptValuesMetaMod.Exception.FieldToReplaceNotFound
What it means
The ScriptValuesMod step is configured with replace=true for a field, but the field to replace could not be found in the incoming row's row metadata (rowMeta.indexOfValue returned < 0), neither by the original field name nor (after falling back) by the rename. Kettle throws this KettleStepException during addValues, aborting the step before any rows are processed.
Solutions
- Open the ScriptValuesMod step and untick 'replace' or set the field name to one that exists in the input stream
- Check which field name the exception names (fieldname or rename) and align it with the upstream row layout (use 'Show input fields')
- Insert a 'Select values' / 'Field exists' step or fix the upstream step so the field is always present before this step
- Verify case-sensitive spelling of the field name — Kettle field lookups are case-sensitive
- Re-save the transformation after step renames so metadata references stay in sync
Example fix
// before: replace=true on missing field fieldname="old_total", rename="", replace=true // row has 'total' // after: point replace at the actual field fieldname="total", rename="", replace=true
Defensive patterns
Strategy: validation
Validate before calling
// validate the step config against the input row layout before running
RowMetaInterface input = transMeta.getPrevStepFields(stepName);
String[] names = meta.getFieldname();
String[] renames = meta.getRename();
boolean[] replace = meta.getReplace();
for (int i = 0; i < names.length; i++) {
if (replace[i] && input.indexOfValue(names[i]) < 0
&& input.indexOfValue(renames[i]) < 0)
throw new KettleException("Replace target not in stream: " + names[i]);
} Try / catch
try {
trans.execute(null);
} catch (KettleException e) {
if (BaseMessages.getString(PKG, "ScriptValuesMetaMod.Exception.FieldToReplaceNotFound")
.matches(Pattern.quote(e.getMessage()).replaceAll("\\{.*\\}", ".*"))) {
logError("Fix the ScriptValuesMod replace field config: " + e.getMessage());
} else throw e;
} Prevention
- After renaming any upstream field, re-open downstream script steps and re-map replace targets
- Remember field lookups are case-sensitive; keep naming conventions consistent
- Use Spoon's 'Show input fields' on the step hop to confirm the replace field exists
- Clear the 'replace' checkbox for fields that are new outputs, not replacements
- Add a unit smoke test that loads the transformation and checks getPrevStepFields against step metadata
When it happens
Trigger: processRow -> addValues with meta.getReplace()[i]==true while meta.getFieldname()[i] is not in the incoming row layout; the fallback lookup of meta.getRename()[i] in the row layout also fails; note the empty-fieldname branch throws this same message even when the name is empty.
Common situations: An upstream step was renamed or removed so the field no longer exists in the stream; field renamed case-sensitively (e.g. 'Name' vs 'name'); transformation edited to rename the output field but 'replace' still points at the old name; the step's 'replace' checkbox left on after changing the field mapping.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- AutoDoc.Exception.FilenameFieldNotFound
- AutoDoc.Exception.FileTypeFieldNotFound
- MultiMergeJoin.Exception.UnableToFindFieldInReferenceStream
- Unable to find the specified fieldname
- AddSequence.Exception.ErrorReadingSequence
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1955b3f01cb0bcd8.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesMod.java:157
// What is the output row looking like?
//
data.outputRowMeta = getInputRowMeta().clone();
meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
metaStore );
// Determine the indexes of the fields used!
//
determineUsedFields( rowMeta );
// Get the indexes of the replaced fields...
//
data.replaceIndex = new int[ meta.getFieldname().length ];
for ( int i = 0; i < meta.getFieldname().length; i++ ) {
if ( meta.getReplace()[ i ] ) {
data.replaceIndex[ i ] = rowMeta.indexOfValue( meta.getFieldname()[ i ] );
if ( data.replaceIndex[ i ] < 0 ) {
if ( Utils.isEmpty( meta.getFieldname()[ i ] ) ) {
throw new KettleStepException( BaseMessages.getString(
PKG, "ScriptValuesMetaMod.Exception.FieldToReplaceNotFound", meta.getFieldname()[ i ] ) );
}
data.replaceIndex[ i ] = rowMeta.indexOfValue( meta.getRename()[ i ] );
if ( data.replaceIndex[ i ] < 0 ) {
throw new KettleStepException( BaseMessages.getString(
PKG, "ScriptValuesMetaMod.Exception.FieldToReplaceNotFound", meta.getRename()[ i ] ) );
}
}
} else {
data.replaceIndex[ i ] = -1;
}
}
// set the optimization level
data.cx = ContextFactory.getGlobal().enterContext();
try {
String optimizationLevelAsString = environmentSubstitute( meta.getOptimizationLevel() );View on GitHub (pinned to f3058517a1)