Skip to content

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

Open
@stuartmorgan-g

Description

@stuartmorgan-g

Imported from dnfield/flutter_svg#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.<anonymous closure>.<anonymous closure> (from package:flutter_svg/src/loaders.dart)
 <- Context num_variables: 2 <- compute.<anonymous closure> (from package:flutter/src/foundation/_isolates_io.dart)
 <- resultPort in Instance of '_RemoteRunner<ByteData>' (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.<anonymous closure> (package:flutter_svg/src/loaders.dart:154)
<asynchronous suspension>
#6      _VectorGraphicWidgetState._loadPicture.<anonymous closure> (package:vector_graphics/src/vector_graphics.dart:355)
<asynchronous suspension>
#7      _VectorGraphicWidgetState._loadPicture.<anonymous closure> (package:vector_graphics/src/vector_graphics.dart:369)
<asynchronous suspension>
#8      _VectorGraphicWidgetState._loadAssetBytes.<anonymous closure> (package:vector_graphics/src/vector_graphics.dart:402)
<asynchronous suspension>

That's because CachingAssetBundle stores futures in its fields, SvgAssetLoader stores bundle (if you provided one) and SvgLoader somehow sends it to other isolate in compute.

Debug build doesn't have this problem because it doesn't use other isolate.

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.

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
  Future<ByteData> _load(BuildContext? context) {
    final SvgTheme theme = getTheme(context);
    return prepareMessage(context).then((T? message) {
      return _compute<T>(
        message: message,
        xml: provideSvg(message),
        theme: theme,
        colorMapper: colorMapper,
      );
    });
  }

  static Future<ByteData> _compute<T>({
    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');
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listp: flutter_svgThe Flutter SVG drawing packagespackageflutter/packages repository. See also p: labels.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions