{"record":{"id":"1e3f914d00dcd11c","repo":"pentaho/pentaho-kettle","slug":"sftpput-error-cannotfindfield","errorCode":null,"errorMessage":"SFTPPut.Error.CanNotFindField","messagePattern":"SFTPPut\\.Error\\.CanNotFindField","errorType":"exception","errorClass":"KettleStepException","httpStatus":null,"severity":"error","filePath":"plugins/sftpput/impl/src/main/java/org/pentaho/di/trans/steps/sftpput/SFTPPut.java","lineNumber":179,"sourceCode":"\n      if ( meta.isInputStream() ) {\n        // Source data is a stream\n        inputStream = new ByteArrayInputStream( getInputRowMeta().getBinary( r, data.indexOfSourceFileFieldName ) );\n\n        if ( data.indexOfRemoteFilename == -1 ) {\n          // for the case when put data is transferred via input field\n          // it is mandatory to specify remote file name\n          throw new KettleStepException( BaseMessages.getString( PKG, \"SFTPPut.Error.RemoteFilenameFieldMissing\" ) );\n        }\n        destinationFilename = getInputRowMeta().getString( r, data.indexOfRemoteFilename );\n      } else {\n        // source data is a file\n        // let's check file\n        file = KettleVFS.getInstance( getTransMeta().getBowl() ).getFileObject( sourceData );\n\n        if ( !file.exists() ) {\n          // We can not find file\n          throw new KettleStepException( BaseMessages.getString( PKG, \"SFTPPut.Error.CanNotFindField\", sourceData ) );\n        }\n        // get stream from file\n        inputStream = KettleVFS.getInputStream( file );\n\n        // Destination filename\n        destinationFilename = file.getName().getBaseName();\n      }\n\n      if ( file != null ) {\n        if ( meta.getAfterFTPS() == JobEntrySFTPPUT.AFTER_FTPSPUT_MOVE ) {\n          String realDestationFolder = getInputRowMeta().getString( r, data.indexOfMoveToFolderFieldName );\n\n          if ( Utils.isEmpty( realDestationFolder ) ) {\n            // Move to destination folder is empty\n            throw new KettleStepException( BaseMessages.getString(\n              PKG, \"SFTPPut.Error.MoveToDestinationFolderIsEmpty\" ) );\n          }\n","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/sftpput/impl/src/main/java/org/pentaho/di/trans/steps/sftpput/SFTPPut.java#L161-L197","documentation":"Thrown when the source file path resolved from the row does not exist on the local/VFS filesystem. SFTPPut resolves the path via KettleVFS and calls file.exists(); if false it aborts the row with this KettleStepException, including the path in the message. It prevents attempting to open a stream on a non-existent file.","triggerScenarios":"processRow reads sourceData (a file path string) from the row, KettleVFS.getFileObject(sourceData) succeeds but file.exists() returns false.","commonSituations":"Upstream step generated a filename that was never written; wrong working directory or relative path; file deleted or moved between steps; variable/environment substitution resolving to an unexpected location; permission issues making existence checks fail.","solutions":["Check the path in the error message and confirm the file exists at that exact location at run time.","Fix variables/relative paths (e.g. use ${Internal.Transformation.Filename.Directory}) so the absolute path is correct.","Ensure the upstream step that writes the file completes before SFTPPut runs (proper hop ordering).","Add an upstream 'Check if file exists' / Filter step to handle missing files gracefully."],"exampleFix":"// before\nString path = \"/data/${TODAY}/export.csv\"; // variable not substituted\n// after\nString path = environmentSubstitute(\"${DATA_DIR}/export.csv\"); // resolves to existing file","handlingStrategy":"validation","validationCode":"File f = new File(environmentSubstitute(sourcePath));\nif (f == null || !f.exists()) {\n  throw new FileNotFoundException(\"Source file missing before SFTPPut: \" + sourcePath);\n}","typeGuard":null,"tryCatchPattern":"try {\n  transform.execute();\n} catch (KettleStepException e) {\n  if (e.getMessage().contains(\"CanNotFindField\") && e.getMessage().contains(path)) {\n    log.error(\"Source file does not exist: \" + path);\n    // route row to an error/retry path\n  } else { throw e; }\n}","preventionTips":["Use absolute, variable-substituted paths (${Internal.Transformation.Filename.Directory}).","Ensure the producing step finishes before SFTPPut (correct hop order).","Check file existence in a prior step and branch on the result.","Verify files are not removed by cleanup jobs between steps."],"tags":["kettle","pentaho","sftp","file-not-found","vfs"],"backgroundTag":"file-not-found","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}