{"record":{"id":"cf06aa02f38e7e30","repo":"pentaho/pentaho-kettle","slug":"failed-to-rename-from-to","errorCode":null,"errorMessage":"Failed to rename from  to ","messagePattern":"Failed to rename from  to ","errorType":"exception","errorClass":"SftpException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSftpSession.java","lineNumber":142,"sourceCode":"  @Override\n  public void delete( String path ) throws SftpException {\n    try {\n      if ( isDirectory( path ) ) {\n        client.rmdir( path );\n      } else {\n        client.remove( path );\n      }\n    } catch ( IOException e ) {\n      throw new SftpException( \"Failed to delete: \" + path, e );\n    }\n  }\n\n  @Override\n  public void rename( String oldPath, String newPath ) throws SftpException {\n    try {\n      client.rename( oldPath, newPath );\n    } catch ( IOException e ) {\n      throw new SftpException( \"Failed to rename from \" + oldPath + \" to \" + newPath, e );\n    }\n  }\n\n  @Override\n  public void close() {\n    try {\n      client.close();\n    } catch ( IOException ignored ) {\n      // Ignore\n    }\n  }\n}\n","sourceCodeStart":124,"sourceCodeEnd":155,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSftpSession.java#L124-L155","documentation":"MinaSftpSession.rename(oldPath, newPath) wraps IOException from client.rename into an SftpException. The rename failed server-side, typically because the source does not exist, the target already exists (SFTP rename usually refuses overwrite), or permissions are insufficient.","triggerScenarios":"Calling rename(oldPath, newPath) when oldPath is missing, newPath already exists and the server does not allow overwriting rename, source and target on paths the user cannot modify, or a dropped session.","commonSituations":"Atomic publish patterns (upload temp then rename) breaking when the destination file was created concurrently, case-only renames on case-insensitive servers, moving files across directories where the target dir is missing.","solutions":["Ensure the target does not exist (delete it first) or use a unique temp name for atomic publish","Verify the source path exists and the target's parent directory exists","Check modify permissions on both source and target directories","Retry on transient IO errors after reconnecting the session"],"exampleFix":"// before\nsession.rename(\"/in/a.csv\", \"/done/a.csv\");\n// after\nif (session.fileExists(\"/done/a.csv\")) { session.delete(\"/done/a.csv\"); }\nsession.rename(\"/in/a.csv\", \"/done/a.csv\");","handlingStrategy":"validation","validationCode":"// ensure source exists and target is free before rename\ntry { session.size(oldPath); } catch (SftpException e) { throw new IllegalStateException(\"source missing: \" + oldPath, e); }\ntry { session.size(newPath); session.delete(newPath); } catch (SftpException ignored) { /* target absent: fine */ }","typeGuard":"boolean canRename(MinaSftpSession s, String from, String to) {\n  try { s.size(from); return true; } catch (SftpException e) { return false; }\n  // plus a target-free check as in validationCode\n}","tryCatchPattern":"try {\n  session.rename(oldPath, newPath);\n} catch (SftpException e) {\n  if (session.fileExists(newPath)) { session.delete(newPath); session.rename(oldPath, newPath); return; }\n  throw new IOException(\"rename \" + oldPath + \" -> \" + newPath + \" failed: \" + e.getCause(), e);\n}","preventionTips":["Delete or version the target name first; SFTP rename rarely overwrites","Use unique temp names + rename for atomic publishes to avoid collisions","Ensure the target directory exists and both paths are within permitted scope","Watch for case-only renames on case-insensitive servers"],"tags":["sftp","ssh","rename","file-already-exists"],"backgroundTag":"file-already-exists","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"}