| name | media-kit-macos-codesign-crash |
| description | Fix Flutter macOS app crash at launch due to media_kit library loading failure. Use when:
(1) macOS app builds successfully but crashes immediately on launch, (2) Crash log shows
"Library not loaded: @rpath/Ass.framework" or similar media_kit framework, (3) Error says
"code signature not valid for use in process: Trying to load an unsigned library",
(4) Problem appears after flutter clean or fresh clone, (5) Codesign script exists in
Podfile but frameworks are still unsigned after build - check build phase ORDER.
Fixes unsigned media_kit native frameworks (Ass.framework, Avcodec.framework, etc.)
by adding post-build codesigning AND ensuring correct build phase ordering.
|
| author | Claude Code |
| version | 2.0.0 |
| date | "2026-02-22T00:00:00.000Z" |
Media Kit macOS Codesign Crash Fix
Problem
Flutter macOS apps using media_kit (video player library) crash immediately at launch after
a clean build. The app builds successfully but fails to start due to unsigned native frameworks.
Context / Trigger Conditions
Root Cause: Build Phase Ordering
The most common cause (especially after pod deintegrate + pod install) is that the Xcode
build phases end up in the wrong order:
WRONG order (codesign runs before frameworks are copied):
1. [CP] Check Pods Manifest.lock
2. Sources
3. Frameworks
4. Resources
5. Bundle Framework
6. ShellScript (Flutter assemble)
7. Codesign media_kit frameworks ← SIGNS NOTHING (frameworks not embedded yet)
8. [CP] Embed Pods Frameworks ← copies frameworks into app bundle
CORRECT order (embed first, then codesign):
1. [CP] Check Pods Manifest.lock
2. Sources
3. Frameworks
4. Resources
5. Bundle Framework
6. ShellScript (Flutter assemble)
7. [CP] Embed Pods Frameworks ← copies frameworks into app bundle
8. Codesign media_kit frameworks ← signs the embedded frameworks
9. FlutterFire upload symbols ← (if applicable, should be last)
Solution
Step 1: Add Codesign Phase via Podfile (if missing)
Add this block inside the post_install do |installer| section:
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == 'media_kit_libs_macos_video'
target.build_configurations.each do |config|
config.build_settings['CODE_SIGN_IDENTITY'] = '-'
end
end
end
main_project = installer.aggregate_targets.first.user_project
main_project.targets.each do |target|
if target.name == 'Runner'
phase_name = 'Codesign media_kit frameworks'
existing_phase = target.shell_script_build_phases.find { |p| p.name == phase_name }
unless existing_phase
phase = target.new_shell_script_build_phase(phase_name)
phase.shell_script = <<-SCRIPT
# Codesign media_kit frameworks with ad-hoc signature
for framework in "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Frameworks"/*.framework; do
if [ -d "$framework" ]; then
codesign --force --deep --sign - "$framework" 2>/dev/null || true
fi
done
SCRIPT
phase.shell_path = '/bin/bash'
end
end
end
main_project.save
Step 2: Verify Build Phase Ordering (CRITICAL)
The Podfile adds the codesign phase but cannot guarantee ordering. After pod install,
check macos/Runner.xcodeproj/project.pbxproj for the Runner target's buildPhases array.
Search for the buildPhases block in the Runner native target section. Ensure this order:
[CP] Embed Pods Frameworks ← MUST be BEFORE codesign
Codesign media_kit frameworks ← MUST be AFTER embed
FlutterFire: upload symbols ← SHOULD be last (if present)
If the order is wrong, swap the lines in the buildPhases array. Example fix:
buildPhases = (
...
3399D490228B24CF009A79C7 /* ShellScript */,
- 9AD7FD721DF2C6A84F6A1FC3 /* Codesign media_kit frameworks */,
- 51BD49356784271F7E3B2B6C /* [CP] Embed Pods Frameworks */,
- BBC532B406767D40236ED3DB /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
+ 51BD49356784271F7E3B2B6C /* [CP] Embed Pods Frameworks */,
+ 9AD7FD721DF2C6A84F6A1FC3 /* Codesign media_kit frameworks */,
+ BBC532B406767D40236ED3DB /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
);
Step 3: Rebuild
flutter clean
flutter pub get
cd macos && pod install && cd ..
flutter run -d macos
Emergency Quick Fix (Manual Codesign)
If you need the app running NOW before fixing build phases:
for fw in build/macos/Build/Products/Debug/<app>.app/Contents/Frameworks/*.framework; do
codesign --force --deep --sign - "$fw"
done
codesign --force --deep --sign - "build/macos/Build/Products/Debug/<app>.app"
open "build/macos/Build/Products/Debug/<app>.app"
Verification
- Build output should show: "warning: Run script build phase 'Codesign media_kit frameworks' will be run during every build"
- App should launch without crash
- Verify frameworks are signed:
codesign -v build/macos/.../app.app/Contents/Frameworks/Ass.framework
Diagnosing Build Phase Order Issues
If the codesign script exists but frameworks are still unsigned, check ordering:
for fw in build/macos/Build/Products/Debug/<app>.app/Contents/Frameworks/*.framework; do
result=$(codesign -v "$fw" 2>&1)
if echo "$result" | grep -q "not signed"; then
echo "UNSIGNED: $(basename $fw)"
fi
done
If ALL media_kit frameworks (Ass, Avcodec, Avformat, etc.) are unsigned but the codesign
script exists in the project, it's almost certainly a build phase ordering problem.
Notes
- This affects debug builds primarily; release builds with proper code signing may not need this
- The
- sign identity means ad-hoc signing (no certificate required)
- Affected frameworks from media_kit include:
Ass.framework, Avcodec.framework,
Avformat.framework, Avutil.framework, Dav1d.framework, Freetype.framework,
Fribidi.framework, Harfbuzz.framework, Mbedcrypto.framework, Mbedtls.framework,
Mbedx509.framework, Mpv.framework, Png16.framework, Swresample.framework,
Swscale.framework, Uchardet.framework, Xml2.framework
- The
|| true in the script prevents build failures if codesigning fails for any framework
- Build phase ordering can silently break after
pod deintegrate + pod install cycles
- The
new_shell_script_build_phase CocoaPods API appends to the end of build phases, which
may be AFTER CocoaPods' own embed phase—but after pod reinstalls, the embed phase can get
re-added at the very end, pushing it AFTER your codesign phase
Related: Duplicate Mpv.framework Warning
If you see ObjC runtime warnings like:
Class Application is implemented in both .../Mpv.framework/Versions/A/Mpv (0xADDR1) and
.../Mpv.framework/Versions/A/Mpv (0xADDR2). This may cause spurious casting failures.
This indicates Mpv.framework is loaded twice, often caused by using a git fork of
media_kit_video alongside pub.dev media_kit_libs_macos_video. The fork's podspec
links -framework Mpv directly while the libs package also vendors it. This can cause
mpv config cache corruption and crashes like:
Assertion failed: (group_index >= 0), function m_config_cache_from_shadow, file m_config_core.c
A clean build usually resolves this. If persistent, consider switching to the released
version of media_kit_video.
References