Description

In Unreal Engine 5.6+, the new shader serialization logic in FShaderMapResourceCode::Serialize does not correctly handle cooked assets that are loaded back into the editor (e.g., from a mounted .pak during a PIE session).

The problematic code (lines 447-456 of ShaderResource.cpp) assumes that ShaderEditorOnlyDataEntries contains entries matching the number of ShaderCodeResources. This assumption is only valid when shaders are saved in the editor. However, when loading cooked materials, ShaderEditorOnlyDataEntries is empty, resulting in an index-out-of-range crash.

This issue prevents loading materials from cooked .pak files during a PIE session. A suggested fix is to wrap the Ar.IsLoading() block inside the existing if (bSerializeEditorOnlyData) conditional, ensuring the code is skipped when editor-only data is not serialized.

Steps to Reproduce

Package a .pak file, containing a material, using settings:

  • Use Pak File: true
  • Use Io Store: false
  • Generate Chunks: true
  • Share Material Shader Code: false
  • Place the material in a content plugin to avoid any path naming conflicts when mounting the generated .pak later
  • Use a primary asset label to place the material in its own .pak chunk, to avoid unrelated files bleeding into the generate .pak

In a separate project, In an editor PIE session:

  • Mount the .pak file: E.g. using `FPakPlatformFile::Mount(<PakFilePath>, 0, [OptionalMountPoint])` (will use default mount point, encoded in .pak, if not specified)
  • Register the mount point to a logical root, e.g. `FPackageName::RegisterMountPoint(<LogicalRoot>, <MountPoint>)`
  • Load the material contained in the .pak, e.g. `UKismetSystemLibrary::LoadAsset_Blocking` and pass in a soft object reference, constructed from a soft object path, to the material, e.g. “/<LogicalRoot>/MaterialInPak.MaterialInPak”
  • Observe that the editor crashes due to FShaderMapResourceCode::Serialize accessing out-of-range ShaderEditorOnlyDataEntries.
Callstack

[Inlined] TArray::operator[](int) Array.h:1149
FShaderMapResourceCode::Serialize(FShaderSerializeContext &) ShaderResource.cpp:454
FShaderMapBase::Serialize(FShaderSerializeContext &) ShaderMap.cpp:366
FMaterialShaderMap::Serialize(FShaderSerializeContext &) MaterialShader.cpp:3889
FMaterial::SerializeInlineShaderMap(FArchive &, const FName &) MaterialShared.cpp:1483
UE::MaterialInterface::Private::SerializeInlineShaderMaps(FArchive &, TArray<…> &, const FName &, const TMap<…> *) Material.cpp:861
UMaterial::Serialize(FArchive &) Material.cpp:3017
FLinkerLoad::Preload(UObject *) LinkerLoad.cpp:4910
FAsyncPackage2::PreloadLinkerLoadExports(FAsyncLoadingThreadState2 &) AsyncLoading2.cpp:7204
FAsyncPackage2::Event_PreloadLinkerLoadExports(FAsyncLoadingThreadState2 &, FAsyncPackage2 *, int) AsyncLoading2.cpp:7632
FEventLoadNode2::Execute(FAsyncLoadingThreadState2 &) AsyncLoading2.cpp:5940
FAsyncLoadEventQueue2::ExecuteSyncLoadEvents(FAsyncLoadingThreadState2 &) AsyncLoading2.cpp:6146
FAsyncLoadingThread2::ProcessAsyncLoadingFromGameThread(FAsyncLoadingThreadState2 &, bool &) AsyncLoading2.cpp:9801
[Inlined] FAsyncLoadingThread2::TickAsyncThreadFromGameThread(FAsyncLoadingThreadState2 &, bool &) AsyncLoading2.cpp:10530
FAsyncLoadingThread2::TickAsyncLoadingFromGameThread(FAsyncLoadingThreadState2 &, bool, bool, double, TArrayView<…>, bool &) AsyncLoading2.cpp:10146
FAsyncLoadingThread2::FlushLoading(TArrayView<…>) AsyncLoading2.cpp:11856
FlushAsyncLoading(TArrayView<…>) AsyncPackageLoader.cpp:354
FlushAsyncLoading(int) AsyncPackageLoader.cpp:323
LoadPackageInternal(UPackage *, const FPackagePath &, unsigned int, FLinkerLoad *, FArchive *, const FLinkerInstancingContext *, const FPackagePath *) UObjectGlobals.cpp:1715
LoadPackage(UPackage *, const FPackagePath &, unsigned int, FArchive *, const FLinkerInstancingContext *, const FPackagePath *) UObjectGlobals.cpp:2079
LoadPackage(UPackage *, const wchar_t *, unsigned int, FArchive *, const FLinkerInstancingContext *) UObjectGlobals.cpp:2055
ResolveName2(UObject *&, TStringBuilderBase<…> &, bool, bool, unsigned int, const FLinkerInstancingContext *) UObjectGlobals.cpp:1221
StaticLoadObjectInternal(UClass *, UObject *, TStringView<…>, TStringView<…>, unsigned int, UPackageMap *, bool, const FLinkerInstancingContext *) UObjectGlobals.cpp:1340
StaticLoadObject(UClass *, UObject *, TStringView<…>, TStringView<…>, unsigned int, UPackageMap *, bool, const FLinkerInstancingContext *) UObjectGlobals.cpp:1409
FSoftObjectPath::TryLoad(FUObjectSerializeContext *) SoftObjectPath.cpp:818
[Inlined] FSoftObjectPtr::LoadSynchronous() SoftObjectPtr.h:87
[Inlined] TSoftObjectPtr::LoadSynchronous() SoftObjectPtr.h:516
[Inlined] UKismetSystemLibrary::LoadAsset_Blocking(TSoftObjectPtr<…>) KismetSystemLibrary.cpp:1445
UObject::execCallMathFunction(UObject *, FFrame &, void *const) ScriptCore.cpp:1088
[Inlined] FFrame::Step(UObject *, void *const) ScriptCore.cpp:511
UObject::execLetObj(UObject *, FFrame &, void *const) ScriptCore.cpp:2923
[Inlined] FFrame::Step(UObject *, void *const) ScriptCore.cpp:511
ProcessLocalScriptFunction(UObject *, FFrame &, void *const) ScriptCore.cpp:1257
[Blueprint] Install RiderLink plugin to see BP function details
ProcessScriptFunction<…>(UObject *, UFunction *, FFrame &, void *const, void [Image Removed](UObject *, FFrame &, void *)) ScriptCore.cpp:1049
`ProcessLocalFunction'::`2'::<lambda_1>::operator()() ScriptCore.cpp:1302
ProcessLocalFunction(UObject *, UFunction *, FFrame &, void *const) ScriptCore.cpp:1319
[Inlined] FFrame::Step(UObject *, void *const) ScriptCore.cpp:511
ProcessLocalScriptFunction(UObject *, FFrame &, void *const) ScriptCore.cpp:1257
[Blueprint] Install RiderLink plugin to see BP function details
UObject::ProcessInternal(UObject *, FFrame &, void *const) ScriptCore.cpp:1346
UFunction::Invoke(UObject *, FFrame &, void *const) Class.cpp:7532
UObject::ProcessEvent(UFunction *, void *) ScriptCore.cpp:2191
[Blueprint] Install RiderLink plugin to see BP function details
AActor::ProcessEvent(UFunction *, void *) Actor.cpp:1496
AActor::BeginPlay() Actor.cpp:4827
AActor::DispatchBeginPlay(bool) Actor.cpp:4762
AWorldSettings::NotifyBeginPlay() WorldSettings.cpp:364
AGameStateBase::HandleBeginPlay() GameStateBase.cpp:209
UWorld::BeginPlay() World.cpp:6010
UGameInstance::StartPlayInEditorGameInstance(ULocalPlayer *, const FGameInstancePIEParameters &) GameInstance.cpp:565
UEditorEngine::CreateInnerProcessPIEGameInstance(FRequestPlaySessionParams &, const FGameInstancePIEParameters &, int) PlayLevel.cpp:3186
UEditorEngine::OnLoginPIEComplete_Deferred(int, bool, FString, FPieLoginStruct) PlayLevel.cpp:1627
UEditorEngine::CreateNewPlayInEditorInstance(FRequestPlaySessionParams &, const bool, EPlayNetMode) PlayLevel.cpp:1891
UEditorEngine::StartPlayInEditorSession(FRequestPlaySessionParams &) PlayLevel.cpp:2910
UEditorEngine::StartQueuedPlaySessionRequestImpl() PlayLevel.cpp:1205
UEditorEngine::StartQueuedPlaySessionRequest() PlayLevel.cpp:1102
UEditorEngine::Tick(float, bool) EditorEngine.cpp:2042
UUnrealEdEngine::Tick(float, bool) UnrealEdEngine.cpp:527
FEngineLoop::Tick() LaunchEngineLoop.cpp:5761
[Inlined] EngineTick() Launch.cpp:60
GuardedMain(const wchar_t *) Launch.cpp:189
LaunchWindowsStartup(HINSTANCE__ *, HINSTANCE__ *, char *, int, const wchar_t *) LaunchWindows.cpp:266
WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int) LaunchWindows.cpp:334

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-315963 in the post.

0
Login to Vote

Unresolved
CreatedAug 27, 2025
UpdatedAug 28, 2025
View Jira Issue