Xcode MTL Validation Crashes App

I don't really know the terminology around this very well, but I was trying to test my Mac OS Catalyst app on Mac OS Sequoia, and the app kept crashing apparently due to MTL validation. I was trying to debug why using a menu (as in File, Edit, View, etc.) would crash. The stack looked roughly like this:

6 -[MTLDebugComputeCommandEncoder setBuffer:offset:attributeStride:atIndex:]  MetalTools
5 _CF_forwarding_prep_0 CoreFoundation
4 ___forwarding___ CoreFoundation
3 -[NSObject doesNotRecognizeSelector:] CoreFoundation
2 objc_exception_throw libobjc.A.dylib
1 __cxa_throw b
0 _Unwind_RaiseException libunwind.dylib

Both Claude and Gemini indicated that there was no flaw in my code, but rather that Xcode was responsible. Sure enough, unchecking the MTL validation checkbox in Xcode stopped the crash from happening.

Hi thinkcomp,

Sorry to hear you are experiencing this issue. Can you confirm the version of macOS you are using?

I was developing initially on Mac OS 12.7.8 and then building for distribution on Mac OS 26.2. Both had the same problem as I recall.

Happened again.

(lldb) bt
* thread #1, queue = 'CGImageProviderCallbackQueue', stop reason = signal SIGABRT
    frame #0: 0x00007ff80d9a0fce libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00000001091549b3 libsystem_pthread.dylib`pthread_kill + 263
    frame #2: 0x00007ff80d922d14 libsystem_c.dylib`abort + 123
    frame #3: 0x00007ff80d9220bb libsystem_c.dylib`__assert_rtn + 314
    frame #4: 0x00007ff816460864 Metal`MTLReportFailure.cold.1 + 43
    frame #5: 0x00007ff81644abc5 Metal`MTLReportFailure + 529
    frame #6: 0x00007ff80e1e6ab1 MetalTools`validateComputeFunctionArguments(id<MTLDevice>, NSString*, NSString, NSArray*, MTLDebugFunctionArgument*, unsigned long, MTLDebugFunctionArgument, unsigned long, MTLDebugFunctionArgument, unsigned long, unsigned long long, MTLDebugFunctionArgument, unsigned long, unsigned long, unsigned long, signed char) + 4525
    frame #7: 0x00007ff80e1e51d5 MetalTools`-[MTLDebugComputeCommandEncoder dispatchThreadgroups:threadsPerThreadgroup:] + 609
    frame #8: 0x00007ff816ccf7b4 CoreImage`CIMetalRenderToTextures + 1157
    frame #9: 0x00007ff816ed976c CoreImage`CI::MetalContext::compute_quad(unsigned int, CI::MetalMainProgram const*, CGSize const&, void const**, unsigned long, CI::Dimensions, CI::Dimensions) + 866
    frame #10: 0x00007ff816cca4d7 CoreImage`CI::MetalContext::render_node(CI::TileTask*, CI::ProgramNode*, CGRect const&, CGRect const&, void const**, __IOSurface**, unsigned long) + 1219
    frame #11: 0x00007ff816ed9bac CoreImage`CI::MetalContext::render_root_node(CI::TileTask*, CI::ProgramNode*, CGRect const&, void () block_pointer, void () block_pointer) + 340
    frame #12: 0x00007ff816edb233 CoreImage`CI::Context::recursive_render(CI::TileTask*, CI::roiKey const&, CI::Node*, bool) + 2181
    frame #13: 0x00007ff816cc9c95 CoreImage`CI::Context::render(CI::ProgramNode*, CGRect const&) + 109
    frame #14: 0x00007ff816f1ef74 CoreImage`invocation function for block in CI::image_render_to_surface(CI::Context*, CI::Image*, CGRect, __IOSurface*, CI::RenderDestination const*) + 56
    frame #15: 0x00007ff816cc31e8 CoreImage`CI::recursive_tile(CI::RenderTask*, CI::Context*, CI::RenderDestination const*, char const*, CI::Node*, CGRect const&, CI::PixelFormat, CI::swizzle_info const&, CI::TileTask* (CI::ProgramNode*, CGRect) block_pointer) + 3514
    frame #16: 0x00007ff816cc1f2f CoreImage`CI::tile_node_graph(CI::Context*, CI::RenderDestination const*, char const*, CI::Node*, CGRect const&, CI::PixelFormat, CI::swizzle_info const&, CI::TileTask* (CI::ProgramNode*, CGRect) block_pointer) + 444
    frame #17: 0x00007ff816f1ecf6 CoreImage`CI::image_render_to_surface(CI::Context*, CI::Image*, CGRect, __IOSurface*, CI::RenderDestination const*) + 2212
    frame #18: 0x00007ff816f1c1d0 CoreImage`CI::RenderToSurface::render(CI::Image*, CI::Context*) const + 1192
    frame #19: 0x00007ff816cc0c5f CoreImage`-[CIContext(CIRenderDestination) _startTaskToRender:toDestination:forPrepareRender:forClear:error:] + 3489
    frame #20: 0x00007ff816cbfeb7 CoreImage`-[CIContext(CIRenderDestination) startTaskToRender:toDestination:error:] + 31
    frame #21: 0x00007ff816cbfceb CoreImage`-[CIContext(CIRenderDestination) startTaskToRender:fromRect:toDestination:atPoint:error:] + 170
    frame #22: 0x00007ff816d50c96 CoreImage`invocation function for block in CI::copyIOSurfaceCallback(void*, CGImageProvider*, __CFDictionary const*) + 201
    frame #23: 0x0000000109524f22 libdispatch.dylib`_dispatch_client_callout + 8
    frame #24: 0x0000000109536800 libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 135
    frame #25: 0x00007ff816d50865 CoreImage`CI::copyIOSurfaceCallback(void*, CGImageProvider*, __CFDictionary const*) + 737
    frame #26: 0x00007ff814b763c6 QuartzCore`CA::Render::copy_image(CGImage*, CGColorSpace*, unsigned int, double, double) + 1948
    frame #27: 0x00007ff814b75c0f QuartzCore`CA::Render::prepare_image(CGImage*, CGColorSpace*, unsigned int, double) + 20
    frame #28: 0x00007ff814b7594b QuartzCore`CA::Layer::prepare_commit(CA::Transaction*) + 553
    frame #29: 0x00007ff814cc7f95 QuartzCore`CA::Context::commit_transaction(CA::Transaction*, double, double*) + 655
    frame #30: 0x00007ff814b51a89 QuartzCore`CA::Transaction::commit() + 777
    frame #31: 0x00007ff810b4670c AppKit`__NSControlTrackMouse_block_invoke.55 + 274
    frame #32: 0x00007ff8106dc140 AppKit`-[NSDragEventTracker trackEvent:usingHandler:] + 1144
    frame #33: 0x00007ff8106db5a7 AppKit`NSControlTrackMouse + 1453
    frame #34: 0x00007ff8106dafd6 AppKit`-[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 121
    frame #35: 0x00007ff8106daea6 AppKit`-[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 679
    frame #36: 0x00007ff8106da276 AppKit`-[NSControl mouseDown:] + 678
    frame #37: 0x00007ff91bf3a4f8 UIKitCore`-[_UINSView didTap:] + 642
    frame #38: 0x00007ff91bd306eb UIKitCore`-[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 44
    frame #39: 0x00007ff91bd3056e UIKitCore`_UIGestureRecognizerSendTargetActions + 109
    frame #40: 0x00007ff91bd30218 UIKitCore`_UIGestureRecognizerSendActions + 328
    frame #41: 0x00007ff91c3da2d8 UIKitCore`-[UIGestureRecognizer _updateGestureForActiveEvents] + 638
    frame #42: 0x00007ff91baa7020 UIKitCore`_UIGestureEnvironmentUpdate + 2799
    frame #43: 0x00007ff91bd2a277 UIKitCore`-[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 448

...

HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 70
    frame #58: 0x00007ff8104daaa9 AppKit`_DPSNextEvent + 927
    frame #59: 0x00007ff8104d9166 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1394
    frame #60: 0x00007ff8104cb818 AppKit`-[NSApplication run] + 586
    frame #61: 0x00007ff81049f79a AppKit`NSApplicationMain + 817
    frame #62: 0x00007ff810771cbd AppKit`_NSApplicationMainWithInfoDictionary + 16
    frame #63: 0x00007ff8238021ff UIKitMacHelper`UINSApplicationMain + 1414
    frame #64: 0x00007ff91ba93bfb UIKitCore`UIApplicationMain + 144
    frame #65: 0x00007ffa1161412c SwiftUI`closure #1 (Swift.UnsafeMutablePointer<Swift.Optional<Swift.UnsafeMutablePointer<Swift.Int8>>>) -> Swift.Never in SwiftUI.KitRendererCommon(Swift.AnyObject.Type) -> Swift.Never + 196
    frame #66: 0x00007ffa11614066 SwiftUI`SwiftUI.runApp<τ_0_0 where τ_0_0: SwiftUI.App>(τ_0_0) -> Swift.Never + 150
    frame #67: 0x00007ffa10fb12af SwiftUI`static SwiftUI.App.main() -> () + 63
  * frame #68: 0x0000000105acded3 PlainSite`static PlainSiteApp.$main(self=PlainSite.PlainSiteApp) at PlainSiteApp.swift:3:1
    frame #69: 0x0000000105ace6b9 PlainSite`main at PlainSiteApp.swift:0
    frame #70: 0x000000011779752e dyld`start + 462
Xcode MTL Validation Crashes App
 
 
Q