Download big files

Bug Description


1. Summary

Downloading big files fails using:
import * as FileSystem from ‘@amazon-devices/expo-file-system’;

App Name: N/A (in development)

Bug Severity
Select one that applies

  • Impacts operation of app

  • Blocks current development

  • Improvement suggestion

  • Issue with documentation (If selected, please share the doc link and describe the issue)

  • Other

2. Steps to Reproduce

//55MB file
//const fileUrl = “ Dropbox
//255MB file
//const fileUrl = “ Dropbox
//incompleteurl
//const fileUrl = “ Dropbox

3. Observed Behavior

Explain what actually happened, noting any discrepancies or malfunctions.

When trying to download big files (+200MB), the process fails

4. Expected Behavior

Describe what you expected the SDK to do under normal operation.

It should download files no matter its size

4.a Possible Root Cause & Temporary Workaround

Fill out anything you have tried. If you don’t know, N/A is acceptable

For what I was able to investigate, it is a limitation when using FileSystem and you have to download in blobs or parts, there is a function in FIleSYstem called createDownloadResumable but that didn’t work out…

import * as FileSystem from '@amazon-devices/expo-file-system';

export async function downloadVideoFile(videoUrl: string): Promise<string> {
  try {
    const videosDir = `${FileSystem.documentDirectory}videos/`;
    const finalPath = `${videosDir}mainVideo.mp4`;
    const tempPath = `${videosDir}mainVideo_temp.mp4`;

    const dirInfo = await FileSystem.getInfoAsync(videosDir);
    if (!dirInfo.exists) {
      await FileSystem.makeDirectoryAsync(videosDir, { intermediates: true });
    }

    // Progress callback (optional)
    const callback = (downloadProgress: FileSystem.DownloadProgressData) => {
      const progress =
        downloadProgress.totalBytesExpectedToWrite > 0
          ? downloadProgress.totalBytesWritten /
            downloadProgress.totalBytesExpectedToWrite
          : 0;
      console.log(`[Downloader] Progress: ${(progress * 100).toFixed(2)}%`);
    };

    // Create resumable download
    const resumableDownload = FileSystem.createDownloadResumable(
      videoUrl,
      tempPath,
      {},
      callback
    );

    // Start download
    const downloadResult = await resumableDownload.downloadAsync();
    if (downloadResult?.status !== 200) {
      throw new Error(
        `Failed to download video. Status: ${downloadResult?.status}`
      );
    }

    // Remove old file if it exists
    const oldInfo = await FileSystem.getInfoAsync(finalPath);
    if (oldInfo.exists) {
      await FileSystem.deleteAsync(finalPath, { idempotent: true });
    }

    // Rename temp to final
    await FileSystem.moveAsync({ from: tempPath, to: finalPath });

    return finalPath;
  } catch (error) {
    console.error('[Downloader] Video download error:', error);
    throw error;
  }
}

5. Logs or crash report

ObjectjsEngine: "hermes"message: "Exception in HostFunction: External memory is too high."stack: "Error: Exception in HostFunction: External memory is too high.\n at __blobCollectorProvider (native)\n at createBlobCollector (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:37190:44)\n at createFromOptions (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:37258:45)\n at get (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:35928:109)\n at anonymous (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:29359:45)\n at call (native)\n at dispatchEvent (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:37109:31)\n at setReadyState (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:36298:31)\n at __didCompleteResponse (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:36067:29)\n at apply (native)\n at anonymous (http://localhost:8081/index.bundle//&platform=kepler&dev=true&minify=false:36221:52)"proto: Objectconstructor: ƒ ()jsEngine: "hermes"message: ""name: "Error"toString: ƒ ()proto: Object

6. Environment

Please fill out the fields related to your bug below:

  • SDK Version: 0.21.4726

  • App State: [Foreground]

  • OS Information
    Please ssh into the device via kepler exec vda shelland copy the output from cat /etc/os-releaseinto the answer section below. Note, if you don’t have a simulator running or device attached kepler exec vda shell will respond with vda: no devices/emulators found

    NAME="OS"
    OE_VERSION="4.0.0"
    OS_MAJOR_VERSION="1"
    OS_MINOR_VERSION="1"
    RELEASE_ID="10"
    OS_VERSION="1.1"
    BRANCH_CODE="TV Ship"
    BUILD_DESC="OS 1.1 (TV Ship/10240280)"
    BUILD_FINGERPRINT="1.0.24028.0(c449c30bb1fb0cc8)/10240280N:user/dev-keys"
    BUILD_VARIANT="user"
    BUILD_TAGS="dev-keys"
    BUILD_DATE="Thu Sep 25 10:31:39 UTC 2025"
    BUILD_TIMESTAMP="1758796299"
    VERSION_NUMBER="1002034028030"
    

:backhand_index_pointing_right: Additional Context


Any Additional Context you would like to provide?
Add any other relevant information, such as recent updates to the SDK, dependencies, or device OS that may affect the bug.

Tested in the app virtual device and on a select firestick

Hi @Yorki_Bonilla,

Thank you for the detailed bug report on the large file download issue with the FileSystem API.

Our team is investigating this “External memory is too high” error that occurs when downloading files over 200MB using @amazon-devices/expo-file-system. We appreciate you providing the comprehensive details including:

  • The error logs showing the memory limitation

  • Your attempted workaround using createDownloadResumable

  • Testing on both the virtual device and Fire TV Stick

  • The specific SDK version (0.21.4726) and OS information

We will provide an update as soon as we have more information on a solution or workaround for handling large file downloads.

Thanks for helping us improve the Vega platform.

Warm regards,
Aishwarya

I realized I put the code I used to “try to solve” the issue, but didn’t put the code that triggered the issue in the first place. Here it is:


import * as FileSystem from ‘@amazon-devices/expo-file-system’;

const videosDir = ${FileSystem.documentDirectory}videos/;

async function ensureVideosDirExists() {
const dirInfo = await FileSystem.getInfoAsync(videosDir);
if (!dirInfo.exists) {
await FileSystem.makeDirectoryAsync(videosDir, { intermediates: true });
}
}

/**

Downloads and stores the video locally.

Replaces any existing file safely.

@param videoUrl Remote Dropbox link from configuration

@returns Local file URI if successful
*/
export async function downloadVideoFile(videoUrl: string): Promise {
try {
await ensureVideosDirExists();
const finalPath = ${videosDir}mainVideo.mp4;
const tempPath = ${videosDir}mainVideo_temp.mp4;

console.log(‘[downloadVideoFile] before download’);
const downloadResult = await FileSystem.downloadAsync(videoUrl, tempPath);
console.log(‘[downloadVideoFile] after download’);
console.log(downloadResult);
if (downloadResult.status !== 200) {
throw new Error(Failed to download video. Status: ${downloadResult.status});
}

const oldInfo = await FileSystem.getInfoAsync(finalPath);
if (oldInfo.exists) {
await FileSystem.deleteAsync(finalPath, { idempotent: true });
}

await FileSystem.moveAsync({ from: tempPath, to: finalPath });
return finalPath;
} catch (error) {
console.error(‘[Downloader] Video download error:’, error);
throw error;
}
}


If you need anything else let me know and I’ll do my best.

Greetings..

Any update on this?

Hi @Yorki_Bonilla,

Thanks for following up. We’ve reproduced the issue and are working with the team on a solution. We’ll update you soon.

Warm regards,
Aishwarya