{"record":{"id":"afc335a26c970639","repo":"pentaho/pentaho-kettle","slug":"vfs-provider-rename-error","errorCode":"vfs.provider/rename.error","errorMessage":"vfs.provider/rename.error","messagePattern":"vfs\\.provider/rename\\.error","errorType":"error_code","errorClass":"FileSystemException","httpStatus":null,"severity":"error","filePath":"plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java","lineNumber":536,"sourceCode":"  protected PutObjectRequest createPutObjectRequest( String bucketName, String key, InputStream inputStream,\n                                                     ObjectMetadata objectMetadata ) {\n    return new PutObjectRequest( bucketName, key, inputStream, objectMetadata );\n  }\n\n  @Override\n  protected void doRename( FileObject newFile ) throws Exception {\n    // no folder renames on S3\n    if ( getType().equals( FileType.FOLDER ) ) {\n      logger.debug( \"recursively moving folder [{}] -> [{}]\", this.getPublicURIString(), newFile.getPublicURIString() );\n      doFolderMove( this, newFile );\n      return;\n    }\n\n    s3ObjectMetadata = fileSystem.getS3Client().getObjectMetadata( bucketName, key );\n\n    if ( s3ObjectMetadata == null ) {\n      // object doesn't exist\n      throw new FileSystemException( \"vfs.provider/rename.error\", this, newFile );\n    }\n\n    S3CommonFileObject dest = (S3CommonFileObject) newFile;\n\n    // 1. copy the file\n    CopyObjectRequest copyObjRequest = createCopyObjectRequest( bucketName, key, dest.bucketName, dest.key );\n    logger.debug( \"copyObject ([{}], [{}]) -> ([{}], [{}])\", bucketName, key, dest.bucketName, dest.key );\n    fileSystem.getS3Client().copyObject( copyObjRequest );\n\n    // 2. delete self\n    delete();\n  }\n\n  private void doFolderMove( FileObject sourceFolder, FileObject targetFolder ) throws FileSystemException {\n    logger.debug( \"creating folder [{}]\", targetFolder.getPublicURIString() );\n    FileObject[] children = sourceFolder.getChildren();\n    targetFolder.createFolder();\n    for ( FileObject child : children ) {","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java#L518-L554","documentation":"Thrown by S3CommonFileObject.doRename() when getObjectMetadata returns null for the source key, meaning the object being renamed does not exist in S3. S3 rename is implemented as copy+delete, and this guard prevents copying a nonexistent source.","triggerScenarios":"Calling rename() on an S3 VFS file whose key was deleted (by another process or a stale cache) between resolution and the rename call.","commonSituations":"Stale VFS cache pointing at a deleted object; race with a concurrent delete; wrong bucket/key casing (S3 keys are case-sensitive); typo in the source URI.","solutions":["Refresh/resolve the FileObject to clear stale cache, then verify the object exists before renaming","Check the exact key spelling and case in the source URI","List the bucket/prefix with the S3 console or CLI to confirm the object exists","Handle the race by re-resolving and retrying, or fail gracefully if the object is already gone"],"exampleFix":"// before\nFileObject dest = fsManager.resolveFile( \"s3://bucket/newname\" );\nsrc.rename( dest );\n// after\nif ( !src.exists() ) {\n  throw new FileNotFoundException( src.getName().getURI() );\n}\nsrc.refresh();\nFileObject dest = fsManager.resolveFile( \"s3://bucket/newname\" );\nsrc.rename( dest );","handlingStrategy":"validation","validationCode":"if ( !src.exists() ) {\n  throw new FileNotFoundException( src.getName().getURI() );\n}\nsrc.refresh(); // flush cached metadata\nif ( !src.exists() ) {\n  throw new FileNotFoundException( \"stale reference: \" + src.getName().getURI() );\n}","typeGuard":"boolean existsOnS3( S3CommonFileObject f ) {\n  return f != null && f.bucketName != null && f.key != null\n    && f.fileSystem.getS3Client().doesObjectExist( f.bucketName, f.key );\n}","tryCatchPattern":"try {\n  src.rename( dest );\n} catch ( FileSystemException e ) {\n  if ( e.getCause() == null && src.getName().equals( e.getInfo()[ 0 ] ) ) {\n    // source vanished: refresh and re-check before retrying\n  }\n  throw e;\n}","preventionTips":["Call refresh() on FileObjects after external S3 modifications","Re-check existence immediately before rename in concurrent environments","Verify key spelling/case — S3 keys are case-sensitive","Enable VFS cache with appropriate TTL or disable caching for rapidly-changing buckets"],"tags":["s3","vfs","rename","not-found"],"backgroundTag":"resource-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"}