Media Kit macOS Codesign Crash Fix

SkillMonitoring & ops

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.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Media Kit macOS Codesign Crash Fix skill

What this skill tells your AI

The instructions your AI receives, as published by divinevideo/divine-mobile in .agents/skills/media-kit-macos-codesign-crash/SKILL.md and read by ahel’s review.

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

  • macOS Flutter app using media_kit or media_kit_video package
  • App builds without errors: "Built build/macos/Build/Products/Debug/divine.app"
  • App crashes immediately on launch with no UI appearing
  • Crash report or console shows:
    Library not loaded: @rpath/Ass.framework/Versions/A/Ass
    Reason: code signature in '...' not valid for use in process: Trying to load an unsigned library
    
  • Often occurs after flutter clean, pod deintegrate + pod install, or fresh git clone
  • CRITICAL: Can also occur when the codesign script EXISTS but runs in the wrong order

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|
  # Add script phase to codesign media_kit frameworks (fixes unsigned library crash)
  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

  # Also add codesigning to the main project's frameworks
  main_project = installer.aggregate_targets.first.user_project
  main_project.targets.each do |target|
    if target.name == 'Runner'
      # Check if script phase already exists
      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

  # ... rest of your existing post_install code ...

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

  1. Build output should show: "warning: Run script build phase 'Codesign media_kit frameworks' will be run during every build"
  2. App should launch without crash
  3. 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:

# Check which frameworks are unsigned in the built app
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

Signals

GitHub stars
265
Forks
55
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
media-kit-macos-codesign-crash
Source
github.com/divinevideo/divine-mobile