Skip to main content

Shiply Flutter Dynamic FAQ

1. Unsupported Scenarios​

1. Build environment chip limitations​

Conch SDK currently supports Linux and Mac Intel chips only. (Older Flutter 3.24 and earlier support Mac only.)

Mac M-series chips (arm64) currently require Rosetta.

2. Isolate hot update is not supported​

Using Isolate in a patch hot update is problematic. Isolate hot update is not supported, nor is hot update of Isolate.spawn, compute, or similar thread-switching code. New threads cannot read the Conch runtime instance. Use @PatchExclude(onlyNode: true) to exclude Isolate call sites from the patch.

Non-Dart code hot update is also unsupported. Diff patches do not support Record syntax before Conch 1.8.0; it is supported in 1.8.0 and later.

3. Dynamic types cannot mark generics​

Dynamic types cannot mark generics, which may cause generic validation errors when calling functions in AOT.

Objects created from dynamic types pass generic validation in AOT, because after the dynamic object is created, the inherited base-class generics are marked correctly afterwards.

This issue is triggered only when all three conditions are met:

  1. At least two layers on the inheritance chain are dynamic classes
  2. Unbounded generics are passed along the inheritance chain, and those unbounded generics are used in two or more ways in the hot update
  3. The function uses unbounded generics from the class and performs unbounded-generic validation

2. Common Questions​

1. Which Flutter versions does Conch support?​

Flutter versionAndroidiOSHarmonyOS
3.16.9SupportedSupported—
3.22.3SupportedSupported—
3.24.5SupportedSupported—
3.27.4SupportedSupportedSupported
3.32.8SupportedSupported—
3.41.9SupportedSupportedSupported

2. Conch-Flutter Not Taking Effect​

Conch takes effect only when enable: true in the project config and the app is built in release mode.

Typical logs when not active:

[ConchLoaderAPI] ConchLoader#load() Conch only takes effect in release build mode (currently in debug mode)
[ConchLoaderAPI] ConchLoader#init() Conch only takes effect in release build mode (currently in debug mode)

Troubleshooting: If you don't see detailed ConchLoader logs, Conch is not active. Then:

  1. Try clearing caches
  2. Verify configuration
  3. Confirm release build mode
  4. Check that the project path contains no Chinese characters—English paths are required

3. How to turn on the debug log switch​

Call ConchCoreAPI.enableDebugLog() to output detailed Conch logs for troubleshooting.

Note: Debug mode affects app performance. Turn it off before production release.

4. Image Asset Hot Update Not Working​

Conch supports hot updating in-app image assets independently of code hot update. It uses a custom conchBundle to load images from local hot-update patch files first.

4.1 Automatic Update (No Extra Configuration)​

If your app uses Flutter's Image.asset, SvgPicture.asset, or AssetImage to load images, Conch handles these automatically after applying a patch.

Add @PatchOnly on the corresponding function and build a patch to hot-update images. Conch loads new images from the updated patch first.

4.2 Manual Configuration (Custom Image Loading)​

For non-standard or custom image loading, Conch cannot detect automatically. Replace the default AssetBundle with Conch's conchBundle:

Usage: Wrap the widget tree with DefaultAssetBundle so all resource loading uses this bundle:

DefaultAssetBundle(
bundle: conchBundle,
child: Widget(),
);

5. IconTreeShakerException when building a patch​

You may see this error when building patches:

Target aot_android_asset_bundle failed: IconTreeShakerException: ConstFinder failure: Unhandled exception:
Bad state: Empty input given.
#0 BinaryBuilder._checkEmptyInput (package:kernel/binary/ast_from_binary.dart:657:29)
#1 BinaryBuilder.readComponent.<anonymous closure> (package:kernel/binary/ast_from_binary.dart:681:7)
#2 Timeline.timeSync (dart:developer/timeline.dart:173:22)
#3 BinaryBuilder.readComponent (package:kernel/binary/ast_from_binary.dart:679:21)
#4 loadComponentFromBytes (package:kernel/kernel.dart:33:28)
#5 loadComponentFromBinary (package:kernel/kernel.dart:28:10)
#6 ConstFinder.findInstances (package:const_finder/const_finder.dart:199:35)
#7 main (file:///Users/xydevops/tgclubDevops/devops_single/workspace/flutter_engine/src/flutter/tools/const_finder/bin/main.dart:103:41)
#8 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:33)
#9 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

To disable icon tree shaking, pass --no-tree-shake-icons to the requested flutter build command

Solution: Add --no-tree-shake-icons when building patches:

flutter build patch --no-tree-shake-icons

6. Exclude Changes from the Patch​

To exclude changes from the patch, use the @PatchExclude() annotation on classes or methods.

  • @PatchExclude(): Excludes the entire file by default; that file cannot be hot-patched.
  • @PatchExclude(onlyNode: true): Excludes a single node only.

Exclude an entire file:

() // The entire file cannot be hot-patched
class SomeClass {
// All changes in this file will not be included in the patch
}

Exclude a single node:

(onlyNode: true)
void someMethod() {
// Only changes to this method will not be included in the patch
}

7. View Diff Patch Differences and Propagation​

When building diff patches, enable the following to inspect differences and propagated content:

conch:
debugDiff: true # Print diff content
debugDiffCall: true # Print content propagated from diff points

8. How to Build Patches for Multiple Versions?​

Multi-version build: Place multiple conch_base_vxxxx.json base files under /conch_base/ in the project. The build outputs one patch per version.

Optional configuration:

conch:
# Version numbers in conch_base_vxx.json files
targetBaseVersions: v8.8.8.8, v9.8.8.8 # When building patches from multiple base files, specify which versions to build

9. AOT snapshotter exits with code -9 during build​

This error is usually caused by one of the following:

9.1 macOS Security Restrictions​

Description: macOS blocked Flutter engine execution.

Solution: Run the script in the SDK package. See the SDK integration guide section on macOS popup handling—run xattr_quarantine_inFlutter.sh in the SDK package.

9.2 Insufficient Android Heap Memory​

Description: Out of memory when building large projects or during resource-intensive operations.

Solution: Increase heap memory in android/gradle.properties:

org.gradle.jvmargs=-Xmx8192M

3. Advanced Usage​

1. Hot-updating third-party packages​

Hotfix covers the main project by default. To hot-update a package from dependencies, add it with moduleIncludes when building the base package. Do not list the main project again. After that, the module supports function hotfix, page hot updates propagate into it, and APIs called in that scope are retained in the base package.

Include only modules you actually change. A large scope significantly increases base package size; avoid adding many third-party libraries.

conch:
moduleIncludes:
- package:xxx

2. Atomic components / base classes​

Changing an atomic component or base class (adding members, changing signatures, or changing the inheritance chain) causes all subclasses to be pulled into a diff patch, which can make the patch much larger. Avoid changing base classes whenever possible.

Was this page helpful?