{"record":{"id":"66433f7e2a74f650","repo":"pentaho/pentaho-kettle","slug":"vfs-provider-copy-missing-file-error","errorCode":"vfs.provider/copy-missing-file.error","errorMessage":"vfs.provider/copy-missing-file.error","messagePattern":"vfs\\.provider/copy-missing-file\\.error","errorType":"error_code","errorClass":"FileSystemException","httpStatus":null,"severity":"error","filePath":"plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java","lineNumber":383,"sourceCode":"      }\n    }\n    return null;\n  }\n\n  /**\n   * Copies the content of the specified file to this file\n   * Uses server-side multipart copy on large files, if both files are S3FileObjects.\n   * If the source is not an S3FileObject or is in a different region, it uses TransferManager to upload the content.\n   * Supports both files and folders as source and destination. Empty source folders are not valid for S3 destination and will be ignored.\n   *\n   * @param file     The FileObject to copy.\n   * @param selector The FileSelector.\n   * @throws FileSystemException If an error occurs during the copy operation.\n   */\n  @Override\n  public void copyFrom( final FileObject file, final FileSelector selector ) throws FileSystemException {\n    if ( !FileObjectUtils.exists( file ) ) {\n      throw new FileSystemException( \"vfs.provider/copy-missing-file.error\", file );\n    }\n\n    // Locate the files to copy across\n    final ArrayList<FileObject> files = new ArrayList<>();\n    file.findFiles( selector, false, files );\n\n    // Copy everything across\n    for ( final FileObject srcFile : files ) {\n      // Skip folders - they will be created automatically when their files are copied, and empty folders do not exist in S3\n      if ( srcFile.getType() == FileType.FOLDER ) {\n        continue;\n      }\n\n      // Calculate the destination key preserving folder structure\n      final S3CommonFileObject dstFile = calculateDestination( file, srcFile );\n\n      // Copy the individual file\n      copySingleFileFrom( srcFile, dstFile );","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/s3-vfs/core/src/main/java/org/pentaho/s3common/S3CommonFileObject.java#L365-L401","documentation":"S3CommonFileObject.copyFrom() first validates that the source FileObject exists before walking it with the selector. If the source cannot be resolved/does not exist it throws FileSystemException('vfs.provider/copy-missing-file.error', sourceFile) — a guard copied from the VFS AbstractFileObject behavior.","triggerScenarios":"Calling copyFrom(file, selector) with a source FileObject that was deleted, never existed, has a typo'd S3 key, or whose attach failed so existence could not be established.","commonSituations":"Pipelines referencing an S3 key generated by a previous step that produced nothing, path case-sensitivity mismatches (S3 keys are case-sensitive), source bucket not accessible to the credentials.","solutions":["Verify the source S3 path/key spelling and case exactly matches the object.","Check exists() on the source before copyFrom() and fail gracefully if absent.","Confirm the source bucket and key are readable with the configured credentials.","Ensure the upstream step actually produced the source object before copying."],"exampleFix":"// before\nsrc.copyFrom( source, Selectors.SELECT_ALL );\n// after\nif ( !source.exists() ) {\n  logger.warn( \"Skipping copy; source missing: {}\", source.getName() );\n  return;\n}\ndst.copyFrom( source, Selectors.SELECT_ALL );","handlingStrategy":"validation","validationCode":"FileObject src = fs.resolveFile( srcUri );\nif ( !src.exists() ) {\n  throw new FileNotFoundException( \"S3 source missing before copy: \" + srcUri );\n}\ndst.copyFrom( src, Selectors.SELECT_ALL );","typeGuard":null,"tryCatchPattern":"try {\n  dst.copyFrom( src, Selectors.SELECT_ALL );\n} catch ( FileSystemException e ) {\n  if ( e.getMessage().contains( \"copy-missing-file\" ) ) {\n    logger.warn( \"Source vanished: {}\", src.getName() );\n    return; // treat as no-op instead of failing the job\n  }\n  throw e;\n}","preventionTips":["Remember S3 keys are case-sensitive — validate exact casing","Add a pre-step asserting the source object exists in the pipeline","Re-check existence right before copy in concurrent workflows","Avoid reusing FileObject handles across long-running steps"],"tags":["s3","vfs","copy","missing-file"],"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"}