@@ -84,10 +84,15 @@ const updateResolvedEncoding = (sftpId, requestedEncoding, resolvedEncoding) =>
8484 return finalResolved ;
8585} ;
8686
87+ const isAsciiString = ( value ) =>
88+ typeof value === "string" && / ^ [ \x00 - \x7F ] * $ / . test ( value ) ;
89+
8790const encodePath = ( input , encoding ) => {
8891 if ( input === undefined || input === null ) return input ;
8992 if ( Buffer . isBuffer ( input ) ) return input ;
9093 if ( encoding === "utf-8" ) return input ;
94+ // Avoid Buffer paths when ASCII-only; keeps compatibility with unpatched ssh2
95+ if ( isAsciiString ( input ) ) return input ;
9196 return iconv . encode ( input , encoding ) ;
9297} ;
9398
@@ -845,12 +850,31 @@ async function listSftp(event, payload) {
845850 throw new Error ( "SFTP channel not ready" ) ;
846851 }
847852
848- const list = await new Promise ( ( resolve , reject ) => {
849- sftp . readdir ( encodedPath , ( err , items ) => {
850- if ( err ) return reject ( err ) ;
851- resolve ( items || [ ] ) ;
853+ let list ;
854+ try {
855+ list = await new Promise ( ( resolve , reject ) => {
856+ sftp . readdir ( encodedPath , ( err , items ) => {
857+ if ( err ) return reject ( err ) ;
858+ resolve ( items || [ ] ) ;
859+ } ) ;
852860 } ) ;
853- } ) ;
861+ } catch ( err ) {
862+ // Retry with string path when ASCII-only and a Buffer path caused issues
863+ if ( Buffer . isBuffer ( encodedPath ) && isAsciiString ( basePath ) ) {
864+ console . warn ( "[SFTP] Retrying readdir with string path after Buffer failure" , {
865+ basePath,
866+ error : err ?. message || String ( err ) ,
867+ } ) ;
868+ list = await new Promise ( ( resolve , reject ) => {
869+ sftp . readdir ( basePath , ( retryErr , items ) => {
870+ if ( retryErr ) return reject ( retryErr ) ;
871+ resolve ( items || [ ] ) ;
872+ } ) ;
873+ } ) ;
874+ } else {
875+ throw err ;
876+ }
877+ }
854878
855879 const detectedEncoding =
856880 requestedEncoding === "auto" ? detectEncodingFromList ( list ) : requestedEncoding ;
0 commit comments