expo: [SDK 50] expo-file-system - `uploadAsync` Error: Unable to upload the file (cancelled)

I am getting this error when we try to upgrade to Expo 50. Nothing I change seems to alter the effect. I investigated a lot of the commits in expo-file-system in the last few months and didn’t see anything suspicious that caught my attention. I’m pretty stumped as to what could be happening here…

Here is what I see when I print the error thrown by uploadAsync:

[Error: Unable to upload the file: 'Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://api.cloudinary.com/v1_1/questmate-testing/auto/upload, NSErrorFailingURLKey=https://api.cloudinary.com/v1_1/questmate-testing/auto/upload, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "BackgroundUploadTask <8403A4A5-8290-4773-A91B-58832FF985F0>.<12>",
    "LocalUploadTask <8403A4A5-8290-4773-A91B-58832FF985F0>.<12>"
), _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundUploadTask <8403A4A5-8290-4773-A91B-58832FF985F0>.<12>, NSLocalizedDescription=cancelled}']

If I stringify the error it prints:

{"code":"ERR_FILESYSTEM_CANNOT_UPLOAD"}

Our call to uploadAsync looks like the following (where parameters is a Record<string, string>):

const uploadResult = await uploadAsync(url, mediaItem.uri, {
    httpMethod: "POST",
    sessionType: FileSystemSessionType.BACKGROUND,
    uploadType: FileSystemUploadType.MULTIPART,
    fieldName: "file",
    parameters,
});

We double checked the config we pass everything looks good. Plus we did not change any code in this area during the upgrade from Expo 49 to Expo 50.

We are using "expo-file-system": "16.0.5"

_Originally posted by @Jackman3005 in https://github.com/expo/expo/issues/26508#issuecomment-1913536491_

About this issue

  • Original URL
  • State: closed
  • Created 5 months ago
  • Reactions: 7
  • Comments: 21 (6 by maintainers)

Most upvoted comments

@alanjhughes Woo! Thanks for the quick fix.

Any idea when we can expect it in a new release?

thank you @Jackman3005! this is very helpful

The issue is fixed on 50.0.6Update expo and it should be fine On 8 Feb 2024, at 17:50, MCR Studio @.***> wrote: I am right to assume that this fix wouldn’t be present in Expo Go yet, correct? I have the latest Expo SDK and the latest expo-file-system and it doesn’t work on Expo Go.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

@alanjhughes Woo! Thanks for the quick fix.

Any idea when we can expect it in a new release?

As per the PR: https://github.com/expo/expo/pull/26880

image

@RRaideRR

const API_HOST = process.env.EXPO_PUBLIC_API_HOST;

const _fileSystemUpload = async ({
  jwtAccessToken,
  endpoint,
  mimeType,
  params = {},
  uri,
}: {
  jwtAccessToken: string;
  endpoint: UploadEndpoint;
  mimeType?: string;
  params?: Record<string, string>;
  uri: string;
}) => {
  if (Platform.OS === "ios") {
    // WARNING: expo 50 FileSystem.uploadAsync doesn't work on iOS
    const formData = new FormData();
    const uriParts = uri.split(".");
    const fileType = uriParts[uriParts.length - 1];

    // @ts-ignore
    formData.append("file", {
      uri,
      name: `file.${fileType}`,
      type: `image/${fileType}`,
    });

    for (const param in params) {
      formData.append(param, params[param]);
    }

    return fetch(`${API_HOST}/api/upload/${endpoint}`, {
      method: "POST",
      body: formData,
      headers: {
        Authorization: `Bearer ${jwtAccessToken}`,
        "Content-Type": "multipart/form-data",
      },
    });
  } else {
    return FileSystem.uploadAsync(`${API_HOST}/api/upload/${endpoint}`, uri, {
      fieldName: "file",
      parameters: params,
      uploadType: FileSystem.FileSystemUploadType.MULTIPART,
      mimeType,
      headers: {
        Authorization: `Bearer ${jwtAccessToken}`,
      },
    });
  }
};

@brentvatne Nope nope. You should be able to:

1. Clone the repo

2. `npm install`

3. `npm run ios`

4. Click "Choose an image"

5. Choose some image

6. (see chosen image)

7. Click "Upload Image"

8. View logs to see the error message shown

Here is a short video of me demonstrating this: Screen.Recording.2024-02-01.at.12.12.58.pm.mov

This is the exact same error I am receiving. The upload endpoint is not relevant, any endpoint will generate the same error.

Thank you for filing this issue! This comment acknowledges we believe this may be a bug and there’s enough information to investigate it. However, we can’t promise any sort of timeline for resolution. We prioritize issues based on severity, breadth of impact, and alignment with our roadmap. If you’d like to help move it more quickly, you can continue to investigate it more deeply and/or you can open a pull request that fixes the cause.

@brentvatne I was able to create a minimal reproduction here. Hopefully you’re able to get the same issue on your machine.

Note that this isn’t exactly what we’re doing in our codebase and I can’t expose the parameters we usually pass with the uploadAsync command. However, it is still resulting in the same error we are getting in our app, so it should be sufficient. If you get past this error and receive errors from Cloudinary, then I think those will be related to the missing parameters I mentioned.

Let me know if I can help further!

Some additional info that might be helpful:

This is an issue that only pertains to iOS at the moment as the Android upload seems to work.

iOS file uri:

"uri": "file:///var/mobile/Containers/Data/Application/80CB0E0A-957D-4A4C-A1E3-86391F0773A8/Library/Caches/ExponentExperienceData/<companyname>/<appname>/ImagePicker/E6F2CB1C-8E2E-4650-99C2-456D9E9BC191.jpg"

Android file uri (Working totally fine):

"uri": "file:///data/user/0/com.heyauto.glovebox/cache/ImagePicker/eed7742d-b840-461e-ae42-0504037392b4.jpeg"

I’m not sure whether or not the uri could be affecting the upload of the ios file, but this may be helpful! I"m not sure if the parsing of the iOS file picker in expo 49 would yield a different uri and therefore a different result.

I tried downgrading to "expo-file-system": "15.4.3" which is the version we were using before upgrading to Expo 50. But it did not compile for the following reason. Looks like references to bundleAssets were removed in 16.0.0

the bundledAssets change would be unrelated - this was a very Expo-specific concept that was only related to “classic builds”, which were sunset in 2023

Note that this issue occurs only with FileSystemUploadType.MULTIPART option which should be the most used one (multer.js doesn’t support binary content uploads for instance).