pentaho/pentaho-kettle · error · KettleException
WriteToLog.Log.CanNotFindField
Error message
WriteToLog.Log.CanNotFindField
What it means
WriteToLog.processRow() resolves each configured log field name against the incoming row layout via getInputRowMeta().indexOfValue(). If a configured field name is not present in the input stream, indexOfValue() returns -1, and the step logs and throws this KettleException so the transformation fails fast. It exists to catch metadata drift between what the step expects and what the previous step actually delivers.
Solutions
- Open the Write To Log step dialog and remove or correct the field name(s) that no longer exist in the incoming stream.
- Run a 'Fields' / input preview on the previous step to see the actual field names and match them exactly (Kettle field names are case-sensitive).
- If fields are dynamic, clear the Fields table or use 'Get Fields' in the dialog to repopulate from the current input metadata.
- Check the transformation after a source schema change (e.g. a table column renamed) and fix dependent steps.
Example fix
// before (configured field no longer in stream)
String[] fieldName = { "customer_name", "amount" };
// after (aligned with actual input row)
String[] fieldName = { "CUSTOMER_NM", "amount" }; // names matching upstream row metadata Defensive patterns
Strategy: validation
Validate before calling
for (String name : writeToLogMeta.getFieldName()) {
if (inputRowMeta.indexOfValue(name) < 0) {
throw new KettleException("Field not in input stream: " + name);
}
} Try / catch
try {
transformation.execute();
} catch (KettleException e) {
if (e.getMessage().contains("WriteToLog.Log.CanNotFindField")) {
// correct the step's field list against actual input metadata, then retry
}
} Prevention
- Use 'Get Fields' in the step dialog instead of typing field names manually.
- Re-validate steps after renaming upstream columns.
- Keep field lists minimal; log whole rows when field names are unstable.
- Add a step-level unit test that checks field resolution against sample metadata.
When it happens
Trigger: Running a transformation where meta.getFieldName()[i] (a field configured in the Write To Log step dialog) does not exist in the input row metadata, i.e. data.fieldnrs[i] < 0. Occurs in processRow() during first-row initialization after all fields are resolved.
Common situations: Renaming or deleting an upstream field without updating the Write To Log step; connecting a different hop into the step; editing the transformation XML/repo by hand; case-sensitive field name mismatch after a database source column change.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- AddSequence.Exception.NoSpecifiedMethod
- A deadlock was detected between steps
- AbsSecurityManager.ERROR_0003_UNABLE_TO_ACCESS_ROLE_BINDING_WEBSVC
- AbsSecurityManager.ERROR_0004_UNABLE_TO_APPLY_LOGICAL_ROLES_TO_RUNTIME_ROLE
- AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/d25263636d10d1b4.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/writetolog/WriteToLog.java:78
}
// Limit hit? skip
if ( rowCounterLimitHit ) {
putRow( getInputRowMeta(), r ); // copy row to output
return true;
}
if ( first ) {
first = false;
if ( meta.getFieldName() != null && meta.getFieldName().length > 0 ) {
data.fieldnrs = new int[meta.getFieldName().length];
for ( int i = 0; i < data.fieldnrs.length; i++ ) {
data.fieldnrs[i] = getInputRowMeta().indexOfValue( meta.getFieldName()[i] );
if ( data.fieldnrs[i] < 0 ) {
logError( BaseMessages.getString( PKG, "WriteToLog.Log.CanNotFindField", meta.getFieldName()[i] ) );
throw new KettleException( BaseMessages.getString( PKG, "WriteToLog.Log.CanNotFindField", meta
.getFieldName()[i] ) );
}
}
} else {
data.fieldnrs = new int[getInputRowMeta().size()];
for ( int i = 0; i < data.fieldnrs.length; i++ ) {
data.fieldnrs[i] = i;
}
}
data.fieldnr = data.fieldnrs.length;
data.loglevel = meta.getLogLevelByDesc();
data.logmessage = Const.NVL( this.environmentSubstitute( meta.getLogMessage() ), "" );
if ( !Utils.isEmpty( data.logmessage ) ) {
data.logmessage += Const.CR + Const.CR;
}
} // end if first
// We don't need to calculate if step log level is lower than the run log levelView on GitHub (pinned to f3058517a1)