pentaho/pentaho-kettle · error · KettleException
SSH.Error.CommandFieldMissing
SSH.Error.CommandFieldMissing
Error message
SSH.Error.CommandFieldMissing
What it means
SSH step's processRow(), when meta.isDynamicCommand() is true, requires the name of the input field holding the command to execute. If that configured field name is empty it throws KettleException 'SSH.Error.CommandFieldMissing' before processing rows. In dynamic-command mode the step cannot know what to send over SSH without this field reference.
Solutions
- Open the SSH step dialog and select the input field that contains the command in the 'command field name' setting
- Ensure the upstream step actually produces that field and that its name matches exactly (case-sensitive)
- If commands are static instead, disable the dynamic-command option and type the command directly
Example fix
// before meta.setDynamicCommand( true ); meta.setcommandfieldname( "" ); // after meta.setDynamicCommand( true ); meta.setcommandfieldname( "cmd" ); // upstream Text File Input field named 'cmd'
Defensive patterns
Strategy: validation
Validate before calling
if ( meta.isDynamicCommand() &&
( meta.getcommandfieldname() == null || meta.getcommandfieldname().isEmpty() ) ) {
throw new IllegalStateException( "SSH step: dynamic command enabled but command field name is empty" );
} Try / catch
try {
sshStep.processRow();
} catch ( KettleException e ) {
if ( e.getMessage().contains( "CommandFieldMissing" ) ) {
// set the command field in step metadata, then reinitialize
}
} Prevention
- Whenever enabling dynamic command mode, immediately pick the command field
- Validate step settings via the dialog's Verify/OK before saving
- Document that static commands should use the non-dynamic option
When it happens
Trigger: Enabling the 'execute commands from field' / dynamic-command option in the SSH step but leaving the 'command field name' setting blank; loading metadata where the commandfieldname attribute was saved empty.
Common situations: Toggling the dynamic option during testing and forgetting to pick the field; renaming a transformation copy where the field name was cleared; building the step programmatically and not calling setcommandfieldname().
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- AddSequence.Exception.NoSpecifiedMethod
- BaseStep.Exception.SourceStepToReadFromCantRunInMultipleCopies
- BaseStep.Exception.TargetStepToWriteToCantRunInMultipleCopies
- BaseStep.Exception.SourceStepToReadFromDoesntExist
- BaseStep.Exception.TargetStepToWriteToDoesntExist
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/d9ece108446c159c.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/ssh/SSH.java:72
Object[] row;
if ( meta.isDynamicCommand() ) {
row = getRow();
if ( row == null ) {
setOutputDone();
return false;
}
if ( first ) {
first = false;
data.outputRowMeta = getInputRowMeta().clone();
data.nrInputFields = data.outputRowMeta.size();
meta.getFields( getTransMeta().getBowl(), data.outputRowMeta, getStepname(), null, null, this, repository,
metaStore );
data.nrOutputFields = data.outputRowMeta.size();
// Check if commands field is provided
if ( meta.isDynamicCommand() ) {
if ( Utils.isEmpty( meta.getcommandfieldname() ) ) {
throw new KettleException( BaseMessages.getString( PKG, "SSH.Error.CommandFieldMissing" ) );
}
// cache the position of the source filename field
data.indexOfCommand = data.outputRowMeta.indexOfValue( meta.getcommandfieldname() );
if ( data.indexOfCommand < 0 ) {
// The field is unreachable !
throw new KettleException( BaseMessages.getString( PKG, "SSH.Exception.CouldnotFindField", meta
.getcommandfieldname() ) );
}
}
}
} else {
if ( !data.wroteOneRow ) {
row = new Object[] {}; // empty row
incrementLinesRead();
data.wroteOneRow = true;
if ( first ) {
first = false;
data.outputRowMeta = new RowMeta();View on GitHub (pinned to f3058517a1)