Issue summary
I hesitated to split this into 2 issues because they are rather tightly coupled
- Issue 1: When
prefix is not set, transferManager.downloadManyFiles does not actually write files locally. This is because destination is undefined.
- Related issue 2: When
prefix is set, file.download(...) attempts to write the file, but is unable to recursively create directory structure on local machine.
Proposed draft PR
#2199
Standard questions
- Is this a client library issue or a product issue? - client library
- Did someone already solve this? - it hasn't been asked yet in the Issue or Stack overflow
- Do you have a support contract? - At work yes, but this is a personal contribution outside work
Environment details
- OS: macOS Catalina
- Node.js version: v16.15.0
- npm version: 8.5.5
@google-cloud/storage version: 6.10.1
Steps to reproduce
Issue 1:
- Implement code example for 'downloadManyFiles' without
prefix
async function downloadDirectory({ bucketId, sourceDirectory }) {
const storage = new Storage();
const transferManager = new TransferManager(storage.bucket(bucketId));
const options = {};
async function downloadFolderWithTransferManager() {
await transferManager.downloadManyFiles(sourceDirectory, options);
}
const res = await downloadFolderWithTransferManager();
}
- Running the function returns no error. However, no files are written locally, and a well-placed console.warn shows that this is because the
destination is undefined. The draft PR contains a suggestion to always generate the destination.

Issue 2:
- Implement same example for 'downloadManyFiles', except we now set
prefix
async function downloadDirectory({ bucketId, sourceDirectory }) {
const storage = new Storage();
const transferManager = new TransferManager(storage.bucket(bucketId));
const options = {
prefix: "hello",
};
async function downloadFolderWithTransferManager() {
await transferManager.downloadManyFiles(sourceDirectory, options);
}
const res = await downloadFolderWithTransferManager();
}
- Running the function returns
ENOENT: no such file or directory, open 'hello/test-folder/'

This is due to the file stream at
|
fileStream |
|
.pipe(writable) |
|
.on('error', callback) |
|
.on('finish', callback); |
attempting to save a directory object locally. It appears that google storage api returns empty directory objects according to google docs here
https://cloud.google.com/knowledge/kb/listing-only-objects-using-gsutil-and-not-directories-000004568. The draft PR proposes to filter out these empty directory objects from the final write.
Thanks, it is my first issue and fork of the repo! Open to feedback. I've already signed the CLA, but kept the PR as draft until the codeowner reviews the issue/intention of the existing design.
Issue summary
I hesitated to split this into 2 issues because they are rather tightly coupled
prefixis not set,transferManager.downloadManyFilesdoes not actually write files locally. This is becausedestinationisundefined.prefixis set,file.download(...)attempts to write the file, but is unable to recursively create directory structure on local machine.Proposed draft PR
#2199
Standard questions
Environment details
@google-cloud/storageversion: 6.10.1Steps to reproduce
Issue 1:
prefixdestinationis undefined. The draft PR contains a suggestion to always generate the destination.Issue 2:
prefixThis is due to the file stream at
nodejs-storage/src/file.ts
Lines 2108 to 2111 in fe9e3a4
Thanks, it is my first issue and fork of the repo! Open to feedback. I've already signed the CLA, but kept the PR as draft until the codeowner reviews the issue/intention of the existing design.