Skip to content

AWS S3: Native crash when calling cancel() on Storage operations #6401

@dkliss

Description

@dkliss

Description

Description:

Calling cancel() on active storage operations causes the application to crash at the native level with no Dart exception or stack trace. The crash affects both download and upload operations and occurs specifically when:

  1. A storage operation is actively transferring data
  2. Progress callbacks are being fired
  3. cancel() is called on the operation

Environment:

  • Platform: macOS, iOS, Android (all native platforms)
  • Amplify Flutter version: 2.6.5
    • amplify_flutter: ^2.6.5
    • amplify_auth_cognito: ^2.6.5
    • amplify_storage_s3: ^2.6.5
    • amplify_api: ^2.6.5
  • Flutter version: 3.35.3 (stable channel)
  • Dart version: 3.9.2

Expected Behavior:

Calling cancel() should gracefully stop the operation and allow the result future to complete with a cancelled state, allowing the application to handle the cancellation properly.

Actual Behavior:

The application crashes immediately with "Lost connection to device" - no Dart exception is caught, indicating a native-level crash in the Amplify SDK that bypasses Dart's exception handling.

Reproduction Steps:

Download Operation (downloadData):

final operation = Amplify.Storage.downloadData(
  path: StoragePath.fromString(key),
  onProgress: (progress) {
    print('Progress: ${progress.transferredBytes}/${progress.totalBytes}');
  },
);

// Start download, let it transfer data for a few seconds
// Then call cancel - app crashes
await operation.cancel();

Download Operation (downloadFile):

final operation = Amplify.Storage.downloadFile(
  localFile: AWSFile.fromPath(localFilePath),
  path: StoragePath.fromString(key),
  onProgress: (progress) {
    print('Progress: ${progress.transferredBytes}/${progress.totalBytes}');
  },
);

// Start download, let it transfer data for a few seconds
// Then call cancel - app crashes
await operation.cancel();

Upload Operation (uploadData):

final payload = StorageDataPayload.bytes(bytes);
final operation = Amplify.Storage.uploadData(
  path: StoragePath.fromString(key),
  data: payload,
  onProgress: (progress) {
    print('Progress: ${progress.transferredBytes}/${progress.totalBytes}');
  },
);

// Start upload, let it transfer data for a few seconds
// Then call cancel - app crashes
await operation.cancel();

Upload Operation (uploadFile):

final operation = Amplify.Storage.uploadFile(
  localFile: AWSFile.fromPath(filePath),
  path: StoragePath.fromString(key),
  onProgress: (progress) {
    print('Progress: ${progress.transferredBytes}/${progress.totalBytes}');
  },
);

// Start upload, let it transfer data for a few seconds
// Then call cancel - app crashes
await operation.cancel();

Frequency: 100% reproducible when cancelling during active data transfer

Categories

  • Analytics
  • API (REST)
  • API (GraphQL)
  • Auth
  • Authenticator
  • DataStore
  • Notifications (Push)
  • Storage

Steps to Reproduce

See above.

Screenshots

No response

Platforms

  • iOS
  • Android
  • Web
  • macOS
  • Windows
  • Linux

Flutter Version

3.35.3

Amplify Flutter Version

2.6.5

Deployment Method

Amplify Gen 2

Schema

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is not working; the issue has reproducible steps and has been reproducedpending-community-responsePending response from the issue opener or other community membersstorageIssues related to the Storage Category

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions