flutter / flutter/flutter

[flutter_svg] Illegal argument in isolate message: object is unsendable - Library:'dart:async' Class: _Future

Open
#158,835 4 comments 1 reaction 0 assignees View on GitHub
found in release: 3.32 has reproducible steps p: flutter_svg P2 package team-engine triaged-engine
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

_Imported from https://github.com/dnfield/flutter_svg/issues/1099_

Original report by @8symbols on Sep 2, 2024

If you provide a `bundle` argument to `SvgPicture.asset` and use `Image.asset(...)`, then in profile and release modes the following exception will be thrown and svg won't be displayed:

Exception

```
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: object is unsendable - Library:'dart:async' Class: _Future@4048458 (see restrictions listed at `SendPort.send()` documentation for more information)
<- _List len:8 (from dart:core)
<- _Map len:1 (from dart:collection)
<- Instance of 'PlatformAssetBundle' (from package:flutter/src/services/asset_bundle.dart)
<- Instance of 'SvgAssetLoader' (from package:flutter_svg/src/loaders.dart)
<- Context num_variables: 2 <- SvgLoader._load.. (from package:flutter_svg/src/loaders.dart)
<- Context num_variables: 2 <- compute. (from package:flutter/src/foundation/_isolates_io.dart)
<- resultPort in Instance of '_RemoteRunner' (from dart:isolate)

#0 Isolate._spawnFunction (dart:isolate-patch/isolate_patch.dart:398)
#1 Isolate.spawn (dart:isolate-patch/isolate_patch.dart:378)
#2 Isolate.run (dart:isolate:285)
#3 compute (package:flutter/src/foundation/_isolates_io.dart:18)
#4 compute (package:flutter/src/foundation/isolates.dart:82)
#5 SvgLoader._load. (package:flutter_svg/src/loaders.dart:154)

#6 _VectorGraphicWidgetState._loadPicture. (package:vector_graphics/src/vector_graphics.dart:355)

#7 _VectorGraphicWidgetState._loadPicture. (package:vector_graphics/src/vector_graphics.dart:369)

#8 _VectorGraphicWidgetState._loadAssetBytes. (package:vector_graphics/src/vector_graphics.dart:402)

```

That's because CachingAssetBundle [stores futures in its fields](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/src/services/asset_bundle.dart#L187), SvgAssetLoader [stores bundle](https://github.com/dnfield/flutter_svg/blob/master/packages/flutter_svg/lib/src/loaders.dart#L363) (if you provided one) and SvgLoader somehow [sends it to other isolate in compute](https://github.com/dnfield/flutter_svg/blob/master/packages/flutter_svg/lib/src/loaders.dart#L154).

Debug build doesn't have this problem because [it doesn't use other isolate](https://github.com/dnfield/flutter_svg/blob/master/packages/flutter_svg/lib/src/utilities/compute.dart#L21).

Reproducible with Flutter 3.24.1 and `flutter_svg: 2.0.10+1`.

Sample app

`assets/any_svg.svg` and `assets/any_png.png` are literally any svg and png files respectively.

```dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

void main() {
runApp(
const MaterialApp(
home: Screen(),
),
);
}

class Screen extends StatelessWidget {
const Screen({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: [
SvgPicture.asset(
'assets/any_svg.svg',
bundle: DefaultAssetBundle.of(context),
),
Image.asset(
'assets/any_png.png',
width: 100.0,
height: 100.0,
),
],
),
);
}
}

```

Problem can be fixed with the following change, but I don't sure how adequate it is.

Change that fixes problem

```dart
Future _load(BuildContext? context) {
final SvgTheme theme = getTheme(context);
return prepareMessage(context).then((T? message) {
return _compute(
message: message,
xml: provideSvg(message),
theme: theme,
colorMapper: colorMapper,
);
});
}

static Future _compute({
required T? message,
required String xml,
required SvgTheme theme,
required ColorMapper? colorMapper,
}) {
return compute((T? message) {
return vg
.encodeSvg(
xml: xml,
theme: theme.toVgTheme(),
colorMapper: colorMapper == null
? null
: _DelegateVgColorMapper(colorMapper),
debugName: 'Svg loader',
enableClippingOptimizer: false,
enableMaskingOptimizer: false,
enableOverdrawOptimizer: false,
)
.buffer
.asByteData();
}, message, debugLabel: 'Load Bytes');
}
```

Contributor guide

Open the contributing guide

Research direction

Start with packages/flutter_svg/lib/src/loaders.dart, especially SvgLoader._load, and compare it with packages/flutter_svg/lib/src/utilities/compute.dart and Flutter's asset_bundle.dart behavior described in the report. Reproduce the sample using a supplied bundle in profile or release mode; done means the SVG loads without an unsendable-isolate-message exception while preserving isolate-based loading where appropriate.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.